Spring MVC非阻塞和阻塞之间的性能差异

时间:2017-12-15 15:57:32

标签: java mysql spring spring-mvc spring-data

我们正在构建的应用程序预计会有大量并发用户。我们正在尝试评估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个并发用户命中每个端点。

阻止通话的结果: enter image description here

非阻塞通话结果: enter image description here

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

总体而言,非阻塞呼叫的吞吐量和平均时间更好。我们可以做出哪些其他改进或我们可以考虑的因素,以使吞吐量更好?

1 个答案:

答案 0 :(得分:1)

1)您的服务器使用同步请求 - 响应模型

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

2)每个新请求的线程创建和作为响应的异步处理都必须返回成本。

实际上,在这种情况下,JVM必须创建更多对象并执行更多任务,并且UC还需要执行更多计划任务,因为您有更多线程。

结论:从服务器端进行异步处理可能会提高性能但不总是

由于机器上有一些可用的CPU线程,因此将多个线程执行的任务划分有助于提高性能。
当您执行与您的情况一样多的请求时,您将无法获得可用的CPU 因此,您将无法获得性能,您将能够并行处理多个客户端#34;但是由于前面提到的UC调度和对象创建,它会降低性能。

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