比线程处理程序更多的连接

More connections than thread handlers

假设我的 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 个获取请求(只是一个获取请求)到:

localhost:8080/async --> 在 5024ms

中响应

localhost:8080/sync --> 在 '6055ms` 内响应

这是有道理的,因为我们只发送一个单个请求。现在,当我使用涉及 255 个并发用户的 Siege 进行负载测试时,事情变得有趣了。

在这种情况下,我的 async API 端点无法处理很多连接。

所以 async 没有那么可扩展。

这取决于我的硬件吗?假设我的硬件能够处理更多的线程处理程序,那么对于重型硬件,异步处理程序是否能够处理更多的事务,因为有更多的线程?

您仍在使用 ForkJoinPool.commonPool() 进行异步调用。我告诉过你它很小,它会被填满。试试这个(我也修复了你的 CompletableFuture 代码,因为它是完全错误的,它只是没有在你的示例中显示)。

CompletableFuture<Void> f = CompletableFuture.runAsync(() -> {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }, Executors.newSingleThreadExecutor());
return f;

现在每个异步调用都有自己的执行器,所以它不会在公共池中阻塞。当然,因为所有异步调用都有自己的执行器,所以这是一个不好的例子。您想要使用共享池,但比公共池大。

它与您的硬件无关(好吧,很少)。它与长 运行 操作与短 运行 操作混合在一起。