我们正在构建的应用程序预计会有大量并发用户。我们正在尝试评估Spring MVC来构建我们的API层。
编写了以下2个处理程序 - 一个阻塞,另一个阻塞:
@RequestMapping("/nblocking")
public DeferredResult<String> nonBlockingProcessing() {
DeferredResult<String> deferredResult = new DeferredResult<>();
executionService.execute(new Runnable() {
@Override
public void run() {
deferredResult.setResult(fetcher.load());
}
});
return deferredResult;
}
@RequestMapping("/blocking")
public String blockingProcessing() {
return fetcher.load();
}
我们通过JMETER运行测试,用3500个并发用户命中每个端点。
在上面的代码中,fetcher.load调用正在对MySql(最大连接数设置为200)和最大大小(50)的连接池进行数据库查询。
总体而言,非阻塞呼叫的吞吐量和平均时间更好。我们可以做出哪些其他改进或我们可以考虑的因素,以使吞吐量更好?
答案 0 :(得分:1)
1)您的服务器使用同步请求 - 响应模型
根据您的结果,您的服务器基于同步请求 - 响应模型,而不是基于异步或事件驱动的模型。
Tomcat,Apache,Weblogic等就是这种情况......以及大多数Java应用程序服务器
在这个模型中,请求的数量通常限制在几十个并发请求中
您在测试中运行了17.000个请求
因此,这意味着许多请求正在等待处理
因此,不同的请求处理不会提高性能,因为服务器已经满了。
2)每个新请求的线程创建和作为响应的异步处理都必须返回成本。
实际上,在这种情况下,JVM必须创建更多对象并执行更多任务,并且UC还需要执行更多计划任务,因为您有更多线程。
结论:从服务器端进行异步处理可能会提高性能但不总是
由于机器上有一些可用的CPU线程,因此将多个线程执行的任务划分有助于提高性能。
当您执行与您的情况一样多的请求时,您将无法获得可用的CPU
因此,您将无法获得性能,您将能够并行处理多个客户端#34;但是由于前面提到的UC调度和对象创建,它会降低性能。
你应该理解在你的情况下,为什么从服务器端异步方式作为同步方式更慢。