【问题标题】:More connections than thread handlers比线程处理程序更多的连接
【发布时间】:2018-01-27 05:06:31
【问题描述】:

假设我的 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 没有那么可扩展。

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

【问题讨论】:

  • 还在做这个,嗯?
  • 你得到异常了吗?错误?
  • @Kayaman,这只是好奇;我对基础架构感兴趣,但找不到足够的信息。
  • 是的,互联网就是这样。缺乏信息。

标签: java spring rest scalability


【解决方案1】:

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

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

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

它与您的硬件没有任何关系(嗯,很少)。它与长期运行的操作和短期运行的操作混合在一起。

【讨论】:

  • 谢谢!我一直在做更多的研究。但是,当我严重超载服务器(许多线程)时,我得到了“Out of native threads 错误”。有什么方法可以解决这个问题?
  • 通过创建更少的线程。服务器限制了常规请求工作线程,但我的示例中的异步线程每次都会创建一个线程,如答案中所述。
  • 我用newCachedPoolThread 创建了一个ExecutorService(做了一些研究),所以现在服务器运行良好。这是一个好方法吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-04
  • 1970-01-01
  • 1970-01-01
  • 2023-03-31
  • 2012-11-14
  • 2016-11-08
相关资源
最近更新 更多