目标:
对tomcat线程扩容
对应的线程池做变更
keepAlive做优化
1.修改主机的host,dns解析优先解析主机上hosts的地址:
sudo vim //etc/hosts
在hosts末尾加上一句:
120.79.75.103:miaoshaserver
2.在jmeter的高级中设置成java,并且将keepAlive的选项打勾,,这样可以将损耗降到最小
3.在阿里云主机上:
pstree -p 16644 //16644是程序的端口号
pstree -p 16644 | wc -l. //可以查看默认tomcat总共起了几个端口
top -H //可以查看端口信息
4.在
5.经验来说4核8g的虚拟机最合适的最大线程数为800,最小的100是为了解决突发问题,当有请求突发访问的时候可以解决。继续vim application.properties
server.port=8090 spring.tomcat.accept-count=1000 //队列等待长度 spring.tomcat.max-threads=800 spring.tomcat.min-spare-threads=100
重启:./deploy.sh &
6.之后使用jmeter工具测试后发现(2000个线程,10秒,100次循环),用pstree -p 16644 | wc -l 后发现最大的tomcat线程数达到了472个,在之前只有40个。
7.再次强调jmeter中keepAlive选项要打勾的原因:服务端与客户端链接的时候,客户端访问服务端建立一个keepAlive的链接,用处就是,当客户端请求服务端响应之后,服务端不要立马断开链接,而是等待着尝试着复用链接,解决了http响应的无状态的每次都要断开链接造成的耗时问题,最早的http1.0的时候是没有keepAlive的请求的,因为资源稀缺,你想,如果每次都客户端请求完都keepAlive不断开,那么服务端的链接数很快就会被用完了。长链接有个好处就是不用每次都断开又新建,减少时耗,尤其是现在很多手机移动端和复杂网络,用户需要不断访问服务端,这样就只要传输数据就可以了,但是这样也有两个问题:
1.比如有的用户之后就没后续操作了,就把网页放在那里了,那这个长链接就是个废链接。
2.ddos的攻击,一些恶意者发起的攻击,也就是发送很多无脑的包,成为攻击者开的后门。
因此需要定制化tomcat的内嵌化开发,这些定制都是在服务端上的
最后。
创建config包,并创建WebServerConfiguration类:当spring容器加载完容器的最后还有一次可以修改,即利用http11NioProtocol定制化需求
package com.imooc.miaoshaproject.config; import org.apache.catalina.connector.Connector; import org.apache.coyote.http11.Http11NioProtocol; import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.boot.web.server.ConfigurableWebServerFactory; import org.springframework.boot.web.server.WebServerFactoryCustomizer; import org.springframework.stereotype.Component; //当spring容器内没有TomcatEmbededServletContainerFactory这个bean时,会把此bean加载进来 @Component //让springboot可以把它加载为一个bean public class WebServerConfiguration implements WebServerFactoryCustomizer<ConfigurableWebServerFactory> { @Override public void customize(ConfigurableWebServerFactory factory) { // 使用对应工厂类提供给我们的接口定制化我们的tomcat connector ( (TomcatServletWebServerFactory)factory).addConnectorCustomizers(new TomcatConnectorCustomizer() { @Override public void customize(Connector connector) { Http11NioProtocol protocol= (Http11NioProtocol) connector.getProtocolHandler(); //定制化keepAliveTimeOut protocol.setSelectorTimeout(30000);//30s,30s没有请求服务,自动断开 //当请求超过10000条就自动断开keepAlive链接 protocol.setMaxKeepAliveRequests(10000); } }); } }
最后在来说一关于单机4核8g的线程数的拐点,经过压力测试可以得出经验是在800,虽然说服务器的tps吞吐量会随着线程数的增多而增多,,但是如果线程数超过了配置的对应拐点后,反而不会增多,因为cup处理不过来这么多线程,忙于线程调度,吞吐量自然上不去。
当线程超过800后会进入缓冲池,但是也不能太长,因为太消耗内存了,队列出队也消耗cpu,所以设置在1000-2000左右就可以了,超过的就拒绝链接
这次压测主要是数据库mysqld的速度过慢,
一般情况下主键查询和唯一索引查询是能接受的查询,一旦到非唯一索引查询,尤其对大企业而言,比如订单状态查询订单,这种几近于全表扫描对数据库的压力是很大的,企业不会接受这种情况。所以后期一般都会分库分表,扩容数据来解决。