前言
本文將從Tomcat性能優化,SpringCloud開啓重試機制,Zuul網關性能參數優化,Ribbon性能參數優化,Feign與Hystrix性能優化等五個方面分享在生產環境如何做好SpringCloud性能優化。
Tomcat性能優化
一般基於SpringCloud的微服務能夠脫離傳統的tomcat,獨立跑起來,SpringBoot功不可沒,其原理是SpringBoot內嵌了tomcat(當然可以換成其他servlet容器,如jetty),能夠以java -jar形式就能跑起來。
所以針對每個springboot服務,我們需要對tomcat的一些參數進行優化,以下是樓主項目組優化的tomcat參數配置,供大家參考。
tomcat參數說明:
maxThreads:tomcat起動的最大線程數,即同時處理的任務個數,默認值爲200acceptCount:當tomcat起動的線程數達到最大時,接受排隊的請求個數,默認值爲100
maxThreads,acceptCount參數應用場景
場景一
tomcat的請求線程數未達到maxThreads最大閥值,tomcat新建線程處理此請求。
場景二
tomcat的請求線程數達到maxThreads最大閥值,tomcat會把當前請求放入隊列,等待空閒線程處理該請求。
場景三
tomcat的請求線程數達到maxThreads最大閥值,並且請求隊列以達到acceptCount的最大閥值,tomcat拒絕請求,返回連接拒絕(connection refused)。
maxThreads調優
一般說服務器性能要從兩個方面說起:
1、cpu計算型指標
如果是cpu計算型請求,那麼系統響應時間的主要限制就是cpu的運算能力,此時maxThreads應該儘量設的小,降低同一時間內爭搶cpu的線程個數,可以提高計算效率,提高系統的整體處理能力
2、io密集型指標
如果是IO密集型請求,例如數據庫讀寫,那麼響應時間的主要限制就變爲等待外部資源,此時maxThreads應該儘量設的大,這樣才能提高同時處理請求的個數,從而提高系統整體的處理能力。
所以大部分情況下,tomcat處理io型請求比較多,比如常見的連數據庫查詢數據進行接口調用。
另外,要考慮tomcat的併發請求量大的情況下,對於服務器系統參數優化,如虛擬機內存設置和linux的open file限制。
maxThreads設置多大合適?
我們知道線程過多,會導致cpu在線程切換時消耗的時間隨着線程數量的增加越來越大;線程太少,服務器的請求響應吞吐量會急劇下降,所以maxThreads的配置絕對不是越大越好。
實際情況是設置maxThreads大小沒有最優解,要根據具體的服務器配置,實際的應用場景不斷的調整和優化。
acceptCount設置多大合適?
儘量與maxThreads的大小保持一致,這個值應該是主要根據應用的訪問峯值與平均值來權衡配置的。
如果設的較小,可以保證接受的請求較快相應,但是超出的請求可能就直接被拒絕
如果設的較大,可能就會出現大量的請求超時的情況,因爲我們系統的處理能力是一定的。
SpringCloud開啓重試機制
Zuul網關性能參數優化
當使用URL進行路由時,則需要對zuul.host.connect-timeout-millis和zuul.host.socket-timeout-millis參數控制超時時間。
zuul.host. connect-timeout-millis: 10000zuul.host. socket-timeout-millis: 60000
Ribbon性能參數優化
請求連接的超時時間
ribbon.ConnectTimeout=60000
請求處理的超時時間
對所有操作請求都進行重試
ribbon.OkToRetryOnAllOperations=false
對當前實例的重試次數,針對同一個服務實例,最大重試次數(不包括首次調用)
對下個實例的重試次數,針同其它的服務實例,最大重試次數(不包括首次server)
ribbon.MaxAutoRetriesNextServer=2
注意Hystrix斷路器的超時時間需要大於ribbon的超時時間,不然不會觸發重試
Feign與Hystrix性能優化
Feign和Ribbon在整合了Hystrix後,首次調用失敗的問題?
在實際項目中,如果使用了Feign,會出現首次調用失敗,造成該問題的原因是:Hystrix默認的超時時間是1秒,如果超過這個時間尚未響應,將會進入fallback代碼。而首次請求往往會比較慢(因爲Spring的懶加載機制,要實例化一些類),這個響應時間可能就大於1秒了。
目前樓主的強烈做法是:禁用Hystrix的超時時間,設爲false
還有一種是官方提倡的是設置超時時間。
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 5000
在實際的項目中親測,這種方式也有不好的地方,如請求時間超過5s會出現請求數據時有時無的情況,給用戶的感覺是系統不穩定,要求整改。
另外,禁用hystrix,官方不推薦。
hystrix超時設置原則
hytrix設置超時時間 > 默認的hytrix超時時間 > ribbon超時時間
問題:一個http請求,如果feign和ribbon都配置了重試機制,異常情況下一共會請求多少次?
請求總次數 n 爲feignClient和ribbon配置參數的笛卡爾積:
n(請求總次數) = feign(默認5次) * (MaxAutoRetries+1) * (MaxAutoRetriesNextServer+1)
其中+1是代表ribbon本身默認的請求。
其實二者的重試機制相互獨立,並無聯繫。但是因爲用了feign肯定會用到ribbon,所以feign的重試機制相對來說比較雞肋,一般會關閉該功能。ribbon的重試機制默認配置爲0,也就是默認是去除重試機制的,建議不要修改。