[英]Play framework async processing and blocking I/O in Java
我的應用程序使用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操作,考慮到這樣的操作無論如何都使用相同的線程池這一事實。 或者也許最好增加默認的線程池大小,在這種情況下不要打擾async api? (這樣至少代碼可讀性會高得多)
我建議您使用Plays F.Promise<A>
設置自己的上下文並在那里運行阻塞/ cpu密集型操作。 與線程一樣,最佳解決方案取決於許多內容,例如內核數量等。
首先在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
}
}
}
}
}
然后在你的控制器中,使用Plays 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上查看。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.