假设我的API中有两个端点(像以前一样在Spring中(:
@RequestMapping("/async")
public CompletableFuture<String> g(){
CompletableFuture<String> f = new CompletableFuture<>();
f.runAsync(() -> {
try {
Thread.sleep(5000);
f.complete("Finished");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread.sleep(1000);
return f;
}
@RequestMapping("/sync")
public String h() throws InterruptedException {
Thread.sleep(5000);
Thread.sleep(1000);
return "Finished";
}
当我发送 2 个 get 请求(只有一个 get 请求(到:
localhost:8080/async
-->5024ms
回应
localhost:8080/sync
--> "6055ms"中的响应
这是有道理的,因为我们只发送一个请求。现在,当我使用 Siege 进行涉及 255 个并发用户的负载测试时,事情变得有趣了。
在这种情况下,我的async
API 终结点无法处理许多连接。
因此,async
不那么可扩展。
这是否取决于我的硬件?假设我有硬件能够处理更多的线程处理程序,那么对于繁重的硬件,异步的硬件是否能够处理更多的事务,因为有更多的线程?
您仍在使用ForkJoinPool.commonPool()
进行异步调用。我告诉过你它很小,它会被填满。试试这个(我也修复了你的CompletableFuture
代码,因为它是完全错误的,它只是没有显示在你的例子中(。
CompletableFuture<Void> f = CompletableFuture.runAsync(() -> {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}, Executors.newSingleThreadExecutor());
return f;
现在,每个异步调用都有自己的执行器,因此它不会在公共池上阻塞。当然,由于所有异步调用都有自己的执行器,所以这是一个不好的例子。您可能希望使用共享池,但要使用比公共池更大的共享池。
它与您的硬件无关(嗯,很少(。它与长时间运行的操作与短期运行操作混合在一起有关。