【问题标题】:Performance difference between Spring MVC non-blocking and blockingSpring MVC 非阻塞和阻塞的性能差异
【发布时间】:2018-05-29 20:54:13
【问题描述】:

我们正在构建的应用程序预计会有大量的并发用户。我们正在尝试评估 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)的连接池进行数据库查询。

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

【问题讨论】:

  • “我们还可以进行哪些其他改进或考虑哪些因素来提高吞吐量?”优化java代码..优化MySQL查询。优化 MySQL 设置..
  • fetcher.load() 指令使用了多少时间?我会检查是否是加载问题

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


【解决方案1】:

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

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

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

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

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

由于机器上有一些可用的 CPU 线程,将由多个线程执行的任务划分为提高性能是有意义的。
由于您执行的请求如此之多,因此您没有可用的 CPU。
因此,您不会获得性能上的提升,您只能“并行”处理多个客户端,但由于前一点中解释的 UC 调度和对象创建,它会降低性能。

你应该明白在你的情况下,为什么从服务器端异步方式比同步方式慢。

【讨论】:

  • 我使用 tomcat 8.5 来部署应用程序。当我们使用 DeferedResult 作为返回类型时,Spring 不会使用 async Servlet 3.1 吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-06
相关资源
最近更新 更多