gpt4 book ai didi

java - 处理 Play Framework 中的阻塞 IO 调用

转载 作者:行者123 更新时间:2023-12-01 14:33:08 24 4
gpt4 key购买 nike

请查看以下类(class),建议使用哪一个类(class)以及它们有何不同..?

// Approach 1
public class Test extends Controller {
private final DatabaseExecutionContext executionContext;

@Inject
public Test(DatabaseExecutionContext executionContext) {
this.executionContext = executionContext;
}

public CompletableFuture<Result> get() throws ExecutionException, InterruptedException {

return io().thenApply(Results::ok);
}

public CompletableFuture<String> io() throws ExecutionException, InterruptedException {
return CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "io";
}, executionContext);

}
}
//Approach 2
public class Test extends Controller {
private final DatabaseExecutionContext executionContext;

@Inject
public Test(DatabaseExecutionContext executionContext) {
this.executionContext = executionContext;
}

public Result get() throws ExecutionException, InterruptedException {

return Results.ok(io());
}

public String io() throws ExecutionException, InterruptedException {
return CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "io";
}, executionContext).join();

}
}

我想了解如何正确处理阻塞 IO 调用。有人能解释一下 Play 框架如何使用 Completable Future,在我看来它仍然是阻塞的并且没有多大意义,并且让我的代码处理本身很糟糕的 CompletableFuture。

最佳答案

Play 对我来说是新手,我想了解如何正确处理阻塞 IO 调用。

嗨!很好的问题。我一直在使用 Play!一段时间以来,我认为您已经无意中遇到了 Play! 中最复杂的问题之一!不得不提供。让我们使用官方游戏吧!文档回答你的问题:

The default configuration is tuned for asynchronous controllers. In other words, the application code should avoid blocking in controllers, i.e., having the controller code wait for an operation. Common examples of such blocking operations are JDBC calls, streaming API, HTTP requests and long computations. [1]

所以回答你的问题:很简单,根本不要使用阻塞调用。 :) 如果您仍想阻止调用,请继续阅读。

谁能解释一下 Play 框架如何使用 Completable Future,在我看来,它仍然是阻塞的,没有多大意义,让我的代码处理本身很糟糕的 CompletableFuture。

您提供的两个示例确实是阻塞的。它们之间有一个细微的差别。带有 CompletableFuture 的 get() 方法会立即退出,没有的 get() 方法不会退出。它将等待阻塞调用完成。第一个将发布 Play!资源来做其他事情,比如处理其他请求。

由于您正在进行阻塞调用,因此您可能需要设计一个关于如何处理它们的策略:

Play Framework is, from the bottom up, an asynchronous web framework. Streams are handled asynchronously using iteratees. Thread pools in Play are tuned to use fewer threads than in traditional web frameworks, since IO in play-core never blocks.

Because of this, if you plan to write blocking IO code, or code that could potentially do a lot of CPU intensive work, you need to know exactly which thread pool is bearing that workload, and you need to tune it accordingly. Doing blocking IO without taking this into account is likely to result in very poor performance from Play Framework, for example, you may see only a few requests per second being handled, while CPU usage sits at 5%. In comparison, benchmarks on typical development hardware (eg, a MacBook Pro) have shown Play to be able to handle workloads in the hundreds or even thousands of requests per second without a sweat when tuned correctly. [2]

这里的文档再次帮助您设计此策略:Best practices for ThreadPools

如果您的应用程序是超高同步的,您可以忘记 CompletableFuture 方法并使用此处描述的方法:https://www.playframework.com/documentation/2.8.x/ThreadPools#Highly-synchronous

关于java - 处理 Play Framework 中的阻塞 IO 调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59501520/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com