欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Jmeter单机测试spring boot高并发实战

程序员文章站 2022-06-12 15:24:01
...

环境:spring boot2.0(redis+Druid)+Jmeter+jdk1.8+myexlipse
高并发:单机环境下能充分利用cpu和io设备的综合利用率就算是高并发。比如4核8G机器单机(我的笔记本)一般1000QPS等。比如吞吐量与响应时间达到平衡。性能测试中不只关注并发数,尤其是单接口性能测试的时候,更多关注吞吐量、响应时间等指标来评估服务端性能。
奔着这个目标,开始测试
首先在Jmeter上创建线程组:
Jmeter单机测试spring boot高并发实战
每秒300线程,增加HTTPRequest,路径为测试接口
拿postman测试接口没有问题,看到响应时间为100ms(100ms响应速度还是可以的吧)

前期准备工作:增加Druid连接池最大连接数:
properties文件配置:

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.initialSize=2
spring.datasource.minIdle=2
spring.datasource.maxActive=1000
spring.datasource.maxWait=6000
spring.datasource.timeBetweenEvictionRunsMillis=60000
spring.datasource.minEvictableIdleTimeMillis=300000
spring.datasource.validationQuery=SELECT 1 FROM DUAL
spring.datasource.testWhileIdle=true
spring.datasource.testOnBorrow=false
spring.datasource.testOnReturn=false
spring.datasource.poolPreparedStatements=true
spring.datasource.maxPoolPreparedStatementPerConnectionSize=20
spring.datasource.filters=stat,wall,log4j
spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
spring.datasource.connectionInitSqls=set names utf8mb4

Druid配置类:

    // 解决 spring.datasource.filters=stat,wall,log4j 无法正常注册进去
    @ConfigurationProperties(prefix = DB_PREFIX)
    class IDataSourceProperties {
        private String url;
        private String username;
        private String password;
        private String driverClassName;
        private int initialSize;
        private int minIdle;
        private int maxActive;
        private int maxWait;
        private int timeBetweenEvictionRunsMillis;
        private int minEvictableIdleTimeMillis;
        private String validationQuery;
        private boolean testWhileIdle;
        private boolean testOnBorrow;
        private boolean testOnReturn;
        private boolean poolPreparedStatements;
        private int maxPoolPreparedStatementPerConnectionSize;
        private String filters;
        private String connectionProperties;

        @Bean     //声明其为Bean实例
        @Primary  //在同样的DataSource中,首先使用被标注的DataSource
        public DataSource dataSource() {
            DruidDataSource datasource = new DruidDataSource();
            datasource.setUrl(url);
            datasource.setUsername(username);
            datasource.setPassword(password);
            datasource.setDriverClassName(driverClassName);

            //configuration
            datasource.setInitialSize(initialSize);
            datasource.setMinIdle(minIdle);
            datasource.setMaxActive(maxActive);
            datasource.setMaxWait(maxWait);
            datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
            datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
            datasource.setValidationQuery(validationQuery);
            datasource.setTestWhileIdle(testWhileIdle);
            datasource.setTestOnBorrow(testOnBorrow);
            datasource.setTestOnReturn(testOnReturn);
            datasource.setPoolPreparedStatements(poolPreparedStatements);
            datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
            try {
                datasource.setFilters(filters);
            } catch (SQLException e) {
                System.err.println("druid configuration initialization filter: " + e);
            }
            datasource.setConnectionProperties(connectionProperties);
            return datasource;
        }
        //下面就是一些geter,setter等等,太多就不一一列出
    }

增加spring bootTomcat最大连接数:

/**
 * 
 * @author hxz
 * @description tomcat配置类,增加最大连接数!
 * @data 2019年12月7日 下午2:53:26
 */
@Configuration
public class TomcatConfig {
	/**
	 * WebServer配置
	 * @return
	 */
    @Bean
    public ConfigurableServletWebServerFactory webServerFactory() {
        TomcatServletWebServerFactory tomcatFactory = new TomcatServletWebServerFactory();
        tomcatFactory.addConnectorCustomizers(new MyTomcatConnectorCustomizer());
        tomcatFactory.setPort(8080);
        tomcatFactory.setContextPath("/api-g");
        return tomcatFactory;
    }
    /**
     * 设置最大连接数
     * @author hxz
     * @description TODO
     * @data 2019年12月7日 下午3:14:32
     */
    class MyTomcatConnectorCustomizer implements TomcatConnectorCustomizer {
    	
        public void customize(Connector connector) {
            Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
            //设置最大连接数               
            protocol.setMaxConnections(20000);
            //设置最大线程数               
            protocol.setMaxThreads(2000);
            protocol.setConnectionTimeout(30000);
        }
    }

}

Jmeter单机测试spring boot高并发实战
好,根据结果图,这一轮Druid+Tomcat增加连接数的方法抗下300线程的并发,但是随之而来的是响应时间的问题,上面讲道
性能测试中不只关注并发数,尤其是单接口性能测试的时候,更多关注吞吐量、响应时间等指标来评估服务端性能
Jmeter单机测试spring boot高并发实战
但是我们的响应时间已经到了惊人的3000ms——4800ms也就是三~四秒钟,这简直是致命的,我准备加上Redis即换成你服务器再来测试:
Jmeter单机测试spring boot高并发实战
可以看到redis增加之后响应速度快了大约20倍,我的理解:一开始速度很快,并且不报错,但是后来接踵而至的红叉,应该是redis连接池,连接得不到释放的问题,
但是随之而来的是访问出错的问题,结转下来是解决办法:
首先说说我的思路吧:按照关系型数据库的方法:

  1. 增加最大连接数
  2. 及时释放连接