SpringCloud性能調優
- 2019 年 11 月 7 日
- 筆記
zuul默認是使用semaphore隔離,並且最大的並發默認是10
1. 修改隔離策略
默認情況下推薦使用 thread 隔離策略
執行緒池提供了比訊號量更好的隔離機制,並且從實際測試發現高吞吐場景下可以完成更多的請求。但是訊號量隔離的開銷更小,對於本身就是10ms以內的系統,顯然訊號量更合適
zuul: ribbon-isolation-strategy: thread ribbon: threadPool: useSeparateThreadPools: true threadPoolKeyPrefix: api-gateway
ribbon-isolation-strategy:修改執行緒隔離策略useSeparateThreadPools:讓每個路由使用獨立的執行緒池threadPoolKeyPrefix:執行緒池前綴
2. 熔斷器並發調優
修改熔斷器的執行緒數量,注意執行緒數不是越多越好
hystrix: threadpool: default: coreSize: 100 maximumSize: 2000 allowMaximumSizeToDivergeFromCoreSize: true maxQueueSize: -1 command: default: execution: isolation: thread: timeoutInMilliseconds: 60000
allowMaximumSizeToDivergeFromCoreSize:允許maximumSize起作用maxQueueSize:如該值為-1,那麼使用的是SynchronousQueue,否則使用的是LinkedBlockingQueuetimeoutInMilliseconds:斷路器的超時時間;如果ribbon配置了重試那麼該值必需大於ribbonTimeout,重試才能生效
3. 使用Undertow代替Tomcat
默認情況下,Spring Boot 使用 Tomcat 來作為內嵌的 Servlet 容器,可以將 Web 伺服器切換到 Undertow 來提高應用性能,Undertow 是紅帽公司開發的一款基於 NIO 的高性能 Web 嵌入式伺服器
Untertow 的特點:
- 輕量級:它是一個 Web 伺服器,但不像傳統的 Web 伺服器有容器概念,它由兩個核心 Jar 包組成,載入一個 Web 應用可以小於 10MB 記憶體
- Servlet3.1 支援:它提供了對 Servlet3.1 的支援
- WebSocket 支援:對 Web Socket 完全支援,用以滿足 Web 應用巨大數量的客戶端
- 嵌套性:它不需要容器,只需通過 API 即可快速搭建 Web 服務
3.1. 移除Tomcat 依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency>
3.2. 增加Untertow 依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-undertow</artifactId> </dependency>
3.3. 配置文件加上Untertow的配置
server: undertow: io-threads: 16 worker-threads: 256 buffer-size: 1024 direct-buffers: true
io-threads:設置IO執行緒數,它主要執行非阻塞的任務,默認會取值cpu核心worker-threads:阻塞任務執行緒池,當執行類似servlet請求阻塞IO操作會從這個執行緒池中取得執行緒,默認值是IO執行緒數*8buffer-size:設置buffer大小,這些buffer會用於伺服器連接的IO操作,有點類似netty的池化記憶體管理direct-buffers:是否分配的直接記憶體(NIO直接分配的堆外記憶體)
二、Feign參數調優
1. 替換OKHttp
在默認情況下 spring cloud feign在進行各個子服務之間的調用時,http組件使用的是jdk的HttpURLConnection,沒有使用執行緒池。
有2種可選的執行緒池:HttpClient和OKHttp
比較推薦OKHttp,請求封裝的非常簡單易用,性能也很ok。
1.1. 添加依賴
<dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> </dependency>
1.2. 修改配置文件
feign: okhttp: enabled: true httpclient: enabled: false max-connections: 1000 max-connections-per-route: 100
max-connections:最大連接數max-connections-per-route:每個url的連接數
2. 開啟Feign請求響應壓縮
開啟壓縮可以有效節約網路資源,但是會增加CPU壓力,建議把最小壓縮的文檔大小適度調大一點
## 開啟Feign請求響應壓縮 feign.compression.request.enabled=true feign.compression.response.enabled=true ## 配置壓縮文檔類型及最小壓縮的文檔大小 feign.compression.request.mime-types=text/xml,application/xml,application/json feign.compression.request.min-request-size=2048
三、Ribbon參數調優
主要調整請求的超時時間,是否重試
如果業務沒有做冪等性的話建議把重試關掉ribbon.MaxAutoRetriesNextServer=0
## 從註冊中心刷新servelist的時間 默認30秒,單位ms ribbon.ServerListRefreshInterval=15000 ## 請求連接的超時時間 默認1秒,單位ms ribbon.ConnectTimeout=30000 ## 請求處理的超時時間 默認1秒,單位ms ribbon.ReadTimeout=30000 ## 對所有操作請求都進行重試,不配置這個MaxAutoRetries不起作用 默認false #ribbon.OkToRetryOnAllOperations=true ## 對當前實例的重試次數 默認0 #ribbon.MaxAutoRetries=1 ## 切換實例的重試次數 默認1 ribbon.MaxAutoRetriesNextServer=0
如果MaxAutoRetries=1和MaxAutoRetriesNextServer=1請求在1s內響應,超過1秒先同一個伺服器上重試1次,如果還是超時或失敗,向其他服務上請求重試1次。那麼整個ribbon請求過程的超時時間為:ribbonTimeout = (ribbonReadTimeout + ribbonConnectTimeout) * (maxAutoRetries + 1) * (maxAutoRetriesNextServer + 1)