Java Spring MVC非阻塞和阻塞的性能差异

Java Spring MVC非阻塞和阻塞的性能差异,java,mysql,spring,spring-mvc,spring-data,Java,Mysql,Spring,Spring Mvc,Spring Data,我们正在构建的应用程序预计将有大量并发用户。我们正在尝试评估SpringMVC以构建我们的API层 编写了以下2个处理程序-一个阻塞处理程序和另一个非阻塞处理程序: @RequestMapping("/nblocking") public DeferredResult<String> nonBlockingProcessing() { DeferredResult<String> deferredResult = new DeferredResult<>

我们正在构建的应用程序预计将有大量并发用户。我们正在尝试评估SpringMVC以构建我们的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();
}
@RequestMapping(“/nblocking”)
公共延迟结果非阻塞处理(){
DeferredResult DeferredResult=新的DeferredResult();
executionService.execute(新的Runnable(){
@凌驾
公开募捐{
deferredResult.setResult(fetcher.load());
}
});
返回延迟结果;
}
@请求映射(“/blocking”)
公共字符串阻止处理(){
返回fetcher.load();
}
我们通过JMETER运行测试,每个端点都有3500个并发用户

阻塞调用的结果:

非阻塞调用的结果:

在上面的代码中,fetcher.load调用正在对MySql(最大连接数设置为200)和最大大小(50)的连接池进行DB查询


总的来说,非阻塞调用的吞吐量和平均时间更好。我们能做什么其他的改进或者我们可以考虑的因素来提高吞吐量? 1)您的服务器使用同步请求-响应模型

根据您的结果,您的服务器基于同步请求-响应模型,而不是异步或事件驱动模型。
Tomcat、Apache、Weblogic等都是如此。。。以及大多数Java应用程序服务器。
在这个模型中,请求的数量通常被限制为几十个并发请求。
您在测试中运行了17000个请求。
因此,这意味着许多请求正在等待处理。
因此,不同的请求处理不会提高性能,因为服务器已满。

2) 为每个新请求创建线程以及作为响应返回的异步处理也有成本。

实际上,在这种情况下,JVM必须创建更多的对象并执行更多的任务,而UC也必须执行更多的调度任务,因为您有更多的线程。

结论:来自服务器端的异步处理可能会提高性能,但并不总是如此

由于计算机上有一些可用的CPU线程,因此将由多个线程执行的任务进行划分有助于提高性能。
由于您执行的请求与您的情况一样多,因此您没有可用的CPU。
因此,您不会提高性能,您只能“并行”处理多个客户机,但这会降低性能,因为UC调度和对象创建已在前一点中解释


你应该理解<强>在你的情况下,为什么从服务器端异步方式比同步方式慢。

“我们可以做些什么改进或考虑因素来提高吞吐量?”优化java代码。优化MySQL查询。优化MySQL设置。
fetcher.load()指令使用多长时间?我会检查这是否是一个加载问题,我使用tomcat 8.5部署应用程序。当我们使用DefferedResult作为返回类型时,Spring不会使用AsyncServlet3.1吗?