通過壓測可以找到服務器的上限, ps -ef |grep java找到java的進程號,然後通過pstree -p 12569 | wc -l可以看到當前java的線程數。當我們的壓測到達一定數量的時候,請求會報錯:
這是可以去看下線程數:
也就是由於server端併發線程數上不去,導致客戶端請求被拒。
首先看下spring-configuration-metadata.json文件,springboot內嵌tomcat容器後,很多配置都在這裏,比如:
其中,我們需要注意以下參數:
server.tomcat.accept-count:等待隊列長度,默認100
server.tomcat.max-connections:最大可被連接數,默認10000
server.tomcat.max-threads:最大工作線程數,默認200
server.tomcat.min-spare-threads:最小工作線程數,默認10
在默認配置下,當連接超過10000後會出現拒絕連接的情況,當併發請求數量超過200+100的時候會拒絕處理。
所以我們可以適當地增加參數:
重啓後可以看到,線程數變多了
這時再進行壓測,再看線程數:
通過top -H可以看到,資源都在mysql和java上
再看下參數,平均值是非常高的,看吞吐量也可以看出只能承受兩百多,這當然是不行的。
接下來我們需要知道tomcat的keepAlive,這是長連接,也就是客戶端請求完服務端後,連接並不斷開,這麼做的好處是降低了客戶端請求服務端建立、斷開連接所消耗的時間,當然也會消耗資源,但由於現在與服務端交互越來越頻繁,所以長連接也很有必要,但爲了保證資源,所以長連接的失效時間也是需要注意的。
keepAliveTimeOut:多少毫秒後不響應的斷開keepalive
maxKeepAliveRequests:多少次請求後keepalive斷開失效
但由於spring-configuration-metadata.json中並沒有關於keepalive的設置,所以我們需要自己通過代碼來定製。
/**
* 當spring容器內沒有TomcatEmbeddedServletContainerFactory這個bean時,會把此bean加載進spring容器中
*/
@Component
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,30秒
protocol.setKeepAliveTimeout(30000);
//客戶端發送超過10000個請求自動斷開
protocol.setMaxKeepAliveRequests(10000);
}
});
}
}
對於單web容器上線:
線程數量:4核8G內存單進程調度線程數在800-1000,1000以上會花費大量時間在cpu調度上。
等待隊列長度:隊列做緩衝池用,但也不能無限長,因爲緩衝區也會消耗內存,出隊入隊也都消耗cpu。
而對於數據庫而言,建立索引也會大大提高查詢效率,出了插入以外都是一樣。對於插入操作後面會進行處理。