当前位置: 首页 > 面试题库 >

在Java中播放框架异步处理和阻止I / O

吕俊哲
2023-03-14
问题内容

我的应用程序使用Play框架来处理REST请求。我需要在http请求处理程序中执行一些可能会持续很长时间的阻塞I /
O操作。同时,我想有效地处理一些短期请求。

如此处所述:

http://www.playframework.com/documentation/2.2.0/JavaAsync

持久的操作可以异步运行。另一方面,如下所述:

http://www.playframework.com/documentation/2.2.x/ThreadPools

Play框架使用相同的默认线程池,在其中执行所有应用程序代码。至少在Java api中,不可能在不同的线程池上运行异步工作。

因此,我的问题是,考虑到这样的操作无论如何都使用相同的线程池,是否值得异步运行可能阻塞的I /
O操作。还是最好增加默认线程池大小,并且在这种情况下不要理会异步api?(这样至少可以提高代码的可读性)


问题答案:

我建议您设置自己的上下文,并使用Play在其中运行阻塞/ CPU密集型操作F.Promise<A>。与线程一样,最佳解决方案取决于许多因素,例如核数等。

首先在中设置您的上下文applications.conf

play {
  akka {
    akka.loggers = ["akka.event.Logging$DefaultLogger", "akka.event.slf4j.Slf4jLogger"]
    loglevel = WARNING
    actor {
      default-dispatcher = {
        fork-join-executor {
          parallelism-min = 1
          parallelism-factor = 2
          parallelism-max = 6
        }
      }
      my-context {
        fork-join-executor {
          parallelism-min = 1
          parallelism-factor = 4
          parallelism-max = 16
        }
      }
    }
  }
}

然后在您的控制器中,使用Play Promises(我使用Java 8)来利用您的上下文:

public static F.Promise<Result> love() {
    ExecutionContext myExecutionContext = Akka.system().dispatchers().lookup("play.akka.actor.my-context");

    F.Promise<Integer> integerPromise = F.Promise.promise(() ->
            LongRunningProcess.run(10000L)
    , myExecutionContext);

    F.Promise<Integer> integerPromise2 = F.Promise.promise(() ->
            LongRunningProcess.run(10000L)
    , myExecutionContext);

    return integerPromise.flatMap(i -> integerPromise2.map(x -> ok()));
}

这样,您的Play应用仍将在default-dispatcher执行上下文中处理持久请求,而阻塞/ CPU密集型将在中运行my-context

我为您演示了一个非常简短的示例,请在github上查看。



 类似资料:
  • 实时的web特性通常需要为每个用户一个大部分时间都处于空闲的长连接. 在传统的同步web服务器中,这意味着需要给每个用户分配一个专用的线程,这样的开销是十分巨大的. 为了减小对于并发连接需要的开销,Tornado使用了一种单线程事件循环的方式. 这意味着所有应用程序代码都应该是异步和非阻塞的,因为在同一时刻只有一个操作是有效的. 异步和非阻塞这两个属于联系十分紧密而且通常交换使用,但是它们并不完全

  • 问题内容: 我想知道(我的Java应用程序的)播放框架版本与我的应用程序的Java版本之间是否有任何联系? 示例:如果我使用play 2.2.1并在计算机上安装了java8。我可以在代码中使用java8吗? 如果有连接。java8的第一个播放版本是什么? 谢谢你妮芙 问题答案: Play 2.3.x是提及Java 8的第一个版本,请参见此处 今天早晨,我正在与我的一位同事交谈,他发现运行2.1.x

  • 在用400k记录查询MongoDb时,我得到了< code>OutOfMemoryError。我收集了大约40万条用户记录。当我试图检索所有用户(在弹性搜索中转储)时,我得到了< code>OutOfMemoryError错误。 我已经浏览过这个链接,在application.config中添加了jvm.memory=-Xms64m -Xmx1024m,但还是一样的异常。 这是我的堆栈跟踪 -

  • 在play,jersey,spring不同于具有池线程的典型多线程服务器。https://jersey.java.net/documentation/latest/async.html https://www.playframework.com/documentation/2.3.x/JavaAsync 一个线程正在侦听,并且在新线程中发生繁重的处理,此外,Web中的非阻塞请求不能与Java中的非

  • 而是使用EventStream而不是ArchivedEventStream,当我运行命令alert(通知)消息时,会转到除原始发件人之外的所有连接套接字,我也可以如何发送到原始发件人。 这是我的模型和控制器,使用WebSocket 事件模型 这是控制器

  • Rest服务器(Play Framework)中的相关问题在负载测试期间出现“读取超时”异常 java版本“1.8.0_31”java(TM)SE运行时环境(Build1.8.0_31-B13)java HotSpot(TM)64位服务器VM(Build25.31-B07,混合模式) 我正在我的本地PC中测试jmeter。我使用了2000个线程,出现了超时异常,并且Socket不知为什么没有关闭。