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

时间:2017-08-18 13:28:34

标签: java spring rest scalability

假设我的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 - &gt; 5024ms

中的回复

localhost:8080/sync - &gt;回应'6055ms`

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

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

所以async不具备可扩展性。

这取决于我的硬件吗?假设我有硬件能够处理更多的线程处理程序,然后使用繁重的硬件,异步的那个能够处理更多的事务,因为有更多的线程吗?

1 个答案:

答案 0 :(得分:0)

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

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

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

它与你的硬件没什么关系(很好,很少)。它与长时间运行的操作混合在一起,与短期运行操作混合在一起。