springboot 内置tomcat 优化(SpringBoot服务器压测对比)

一、前言

昨天发了一个《SpringBoot服务器压测对比(jetty、tomcat、undertow)》,本是工作的一个笔记,没想到被红薯翻牌了(荣幸之至)。看了OSCer的回复,感觉需要重新梳理下,因为确实存在描述不清和不合理的配置。

这篇博客的目的,不是复述上一篇博客,而是尽量规范的去做一次压测对比,并且能够清晰的描述出过程和结果。

二、准备1、服务器

为了保证尽量少的干扰,这里不再在虚拟机上运行服务,而是直接在物理机上运行服务,并且在这台物理机上安装ab工具。

服务器配置是2个CPU,单个CPU8核,总共内存40G,1T的RAID5机械硬盘。服务器安装的系统是Centos7.5,系统优化同《Centos7高并发优化》所述。但额外的,因工作需要,这台物理机上有6个虚机,是不能关闭的。以下是简单的top展示:

springboot 内置tomcat 优化(SpringBoot服务器压测对比)(1)

2、测试项目

感谢@TGVvbmFyZA 的建议,测试项目不再使用生产项目,而是从Springboot官网打包2.x版本的项目,这样的目的是减少生产项目中不必要的依赖,从而避免不必要的开销。以下是简单的项目介绍:

序号

名称

版本

1

springboot

2.1.1

2

java

1.8

我已将项目放到Gitee,地址:https://gitee.com/loveliyiyi/test4server

以下贴出关键代码,以便更好理解。

package com.shy.test4server; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.context.request.async.WebAsyncTask; /** * @ClassName: TestController * @Description: TODO(这里用一句话描述这个类的作用) * @author chengcai.shang@cmgplex.com * @date 2018年12月7日 上午9:36:25 * */ @Controller @RequestMapping("/test") public class TestController { /** * 未使用HTTP异步的接口 * * @Title: testCeilingNoAsync * @Description: TODO(这里用一句话描述这个方法的作用) * @date 2018年12月7日 上午9:40:57 */ @GetMapping("/testCeilingNoAsync") public String testCeilingNoAsync() { return ""; } /** * 使用HTTP异步的接口 * * @Title: testCeilingNoAsync * @Description: TODO(这里用一句话描述这个方法的作用) * @date 2018年12月7日 上午9:40:57 */ @GetMapping("/testCeilingWithAsync") public WebAsyncTask<String> testCeilingWithAsync() { return new WebAsyncTask(() -> { return ""; }); } }

3、项目优化

不同的服务器容器优化参数均不一致,以下是本次测试主要优化的地方:

序号

服务容器

优化参数

1

tomcat

最大连接数server.tomcat.max-threads=400

2

jetty

最大连接数(400)和最小连接数(10)

3

undertow

cpu核数(16)和工作线程数(400)

4

http异步

线程池core=10,max=400,queue=200

以下优化步骤:

针对tomcat,在application.properties中加入server.tomcat.max-threads=400即可。

针对jetty,在config目录加入JettyConfig类

package com.shy.test4server.config; import org.apache.catalina.Server; import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * @ClassName: JettyConfig * @Description: TODO(这里用一句话描述这个类的作用) * @date 2018年12月7日 上午9:53:46 * */ @Configuration public class JettyConfig { @Bean public JettyEmbeddedServletContainerFactory jettyEmbeddedServletContainerFactory( JettyServerCustomizer jettyServerCustomizer) { JettyEmbeddedServletContainerFactory factory = new JettyEmbeddedServletContainerFactory(); factory.addServerCustomizers(jettyServerCustomizer); return factory; } @Bean public JettyServerCustomizer jettyServerCustomizer() { return server -> { threadPool(server); }; } private void threadPool(Server server) { // Tweak the connection config used by Jetty to handle incoming HTTP // connections final QueuedThreadPool threadPool = server.getBean(QueuedThreadPool.class); // 默认最大线程连接数200 threadPool.setMaxThreads(100); // 默认最小线程连接数8 threadPool.setMinThreads(20); // 默认线程最大空闲时间60000ms threadPool.setIdleTimeout(60000); } }

针对undertow,在application.properties中加入server.undertow.io-threads=16和server.undertow.worker-threads=400即可

针对http异步,优化代码如下:

package com.shy.test4server.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer; /** * @ClassName: SpringmvcConfig * @Description: TODO(这里用一句话描述这个类的作用) * @date 2018年12月7日 上午9:59:06 * */ @Configuration public class SpringmvcConfig { @Bean public void configThreadPoll(AsyncSupportConfigurer asyncSupportConfigurer) { ThreadPoolTaskExecutor threadPool = new ThreadPoolTaskExecutor(); threadPool.setCorePoolSize(10); threadPool.setMaxPoolSize(400); threadPool.setQueueCapacity(200); threadPool.initialize(); asyncSupportConfigurer.setTaskExecutor(threadPool); } }

另,所有测试中,日志均关闭。

三、压测方案

由于三个服务器的优化参数不一致,没法做统一配置,然后观察结果。故只能不断调整参数获取最大的结果,然后比对最终结果,虽然这样得出结果有点片面,但目前也只能这么干。另外,不再辅以Jprofiler监控,因为Jprofiler会影响一定得性能。以下是压测步骤:

1、使用tomcat,压测两个接口,按不同并发访问10000次,然后不断调整参数,获取最大结果。由此可得出纯tomcat和tomcat http异步的结果。

2、使用jetty,压测两个接口,按不同并发访问10000次,然后不断调整参数,获取最大结果。由此可得出纯jetty和jetty http异步的结果。

3、使用udertow,压测两个接口,按不同并发访问10000次,然后不断调整参数,获取最大结果。由此可得出纯udertow和udertow http异步的结果。

四、压测过程1、tomcat

启动命令

java -server -Dserver.tomcat.max-threads=400 -Dspringmvc.thread.core=10 -Dspringmvc.thread.max=400 -Dspringmvc.thread.queue=200 -Xms512m -Xmx512m -jar test4server.jar

压测命令

ab -n 10000 -c 50 http://localhost:8080/test/testCeilingNoAsync ab -n 10000 -c 100 http://localhost:8080/test/testCeilingNoAsync ab -n 10000 -c 200 http://localhost:8080/test/testCeilingNoAsync ab -n 10000 -c 50 http://localhost:8080/test/testCeilingWithAsync ab -n 10000 -c 100 http://localhost:8080/test/testCeilingWithAsync ab -n 10000 -c 200 http://localhost:8080/test/testCeilingWithAsync

压测结果:

springboot 内置tomcat 优化(SpringBoot服务器压测对比)(2)

2、jetty

启动命令

java -server -Djetty.thread.max=400 -Djetty.thread.min=10 -Dspringmvc.thread.core=10 -Dspringmvc.thread.max=400 -Dspringmvc.thread.queue=200 -Xms512m -Xmx512m -jar test4server.jar

压测命令

ab -n 10000 -c 50 http://localhost:8080/test/testCeilingNoAsync ab -n 10000 -c 100 http://localhost:8080/test/testCeilingNoAsync ab -n 10000 -c 200 http://localhost:8080/test/testCeilingNoAsync ab -n 10000 -c 50 http://localhost:8080/test/testCeilingWithAsync ab -n 10000 -c 100 http://localhost:8080/test/testCeilingWithAsync ab -n 10000 -c 200 http://localhost:8080/test/testCeilingWithAsync

压测结果:

springboot 内置tomcat 优化(SpringBoot服务器压测对比)(3)

3、undertow

启动命令

java -server -Dserver.undertow.io-threads=16 -Dserver.undertow.worker-threads=400 -Dspringmvc.thread.core=10 -Dspringmvc.thread.max=400 -Dspringmvc.thread.queue=200 -Xms512m -Xmx512m -jar test4server.jar

压测命令

ab -n 10000 -c 50 http://localhost:8080/test/testCeilingNoAsync ab -n 10000 -c 100 http://localhost:8080/test/testCeilingNoAsync ab -n 10000 -c 200 http://localhost:8080/test/testCeilingNoAsync ab -n 10000 -c 50 http://localhost:8080/test/testCeilingWithAsync ab -n 10000 -c 100 http://localhost:8080/test/testCeilingWithAsync ab -n 10000 -c 200 http://localhost:8080/test/testCeilingWithAsync

压测结果:

springboot 内置tomcat 优化(SpringBoot服务器压测对比)(4)

五、压测结果1、关于HTTP异步

HTTP异步的目的在帮助dispatcherservlet分担压力,提升吞吐量。但如果运行在NIO模式的服务容器上,就会产生负面影响,因为NIO本身就做了类似的事情,此时再加HTTP异步,则相当于又加了N多不必要的线程,导致性能主要消耗在线程的开销上,所以建议使用tomcat作为内嵌容器并且没有开启tomcat的NIO模式时,可以配合HTTP异步来提升程序性能。尤其是当业务繁重时,提升效果尤其明显。

2、关于服务容器

在基于天花板接口的测试中,综合对比tomcat、jetty、undertow,可以发现undertow相对性能更高点。但此结果并不一定准确,因为测试方案里只进行了很简单的参数调整,以及并没有针对实际业务代码进行测试。不过源码我已提供,有兴趣的可以实际测试下。

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页