后续之《SpringBoot服务器压测对比(jetty、tomcat、undertow)》

1、前言

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

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

2、准备

    一、服务器

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

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

    二、测试项目

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

序号 名称 版本
1 springboot 2.1.1
2 java 1.8

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

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

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 "";
		});
	}
}

    三、项目优化

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

序号 服务容器 优化参数
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);
	}
}

        另,全部测试中,日志均关闭。

3、压测方案

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

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

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

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

4、压测过程

    一、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

        压测结果:

    二、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

        压测结果:

    三、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

        压测结果:

5、压测结果

    一、关于HTTP异步

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

    二、关于服务容器

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

相关文章
相关标签/搜索