zuul默認是使用semaphore隔離,並且最大的併發默認是100,請求的併發線程超過100就會報錯,zuul裡隔離是按服務隔離的,也就是1個服務1個信號量,非接口級別的
hystrix改用線程池的好處
- 加快響應速度
- 合理利用CPU和內存
- 統一管理
- zuul接受到大量請求時,使用線程池技術是非常合適的,它可以大大減少線程的創建和銷燬次數,提高服務器的工作銷量
線程池核心原理
線程池運行原理
zuul使用hystrix線程池技術
注意zuul服務本身的線程池大小,後端服務的線程池大小,以及隔離信號量或線程池的線程池大小,防止1個線程被佔用光
1. 修改Hystrix隔離策略
Hystrix線程隔離
認證中心線程池
用戶中心線程池高併發情況下推薦使用 thread 隔離策略
線程池提供了比信號量更好的隔離機制,並且從實際測試發現高吞吐場景下可以完成更多的請求。但是信號量隔離的開銷更小,對於本身就是10ms以內的系統,顯然信號量更合適
<code>zuul: ribbon-isolation-strategy: thread # 提高吞吐量 host: max-per-route-connections: 60000 # 適用於ApacheHttpClient,如果是okhttp無效。每個服務的http客戶端連接池最大連接,默認是200 max-total-connections: 60000 # 適用於ApacheHttpClient,如果是okhttp無效。每個route可用的最大連接數,默認值是20 ribbon: eager-load: enabled: true threadPool: useSeparateThreadPools: true threadPoolKeyPrefix: api-gateway/<code>
ribbon-isolation-strategy:修改線程隔離策略useSeparateThreadPools:讓每個路由使用獨立的線程池threadPoolKeyPrefix:線程池前綴
2. 熔斷器併發調優
修改熔斷器的線程數量,注意線程數不是越多越好
<code>hystrix: threadpool: default: coreSize: 100 maximumSize: 5000 allowMaximumSizeToDivergeFromCoreSize: true maxQueueSize: -1 command: default: circuitBreaker: foreOpen: false execution: timeout: enabled: true isolation: thread: timeoutInMilliseconds: 900000 /<code>
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 依賴
<code><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>/<code>
3.2. 增加Untertow 依賴
<code><dependency><groupid>org.springframework.boot/<groupid><artifactid>spring-boot-starter-undertow/<artifactid>/<dependency>/<code>
3.3. 配置文件加上Untertow的配置
<code>server: undertow: io-threads: 16 worker-threads: 256 buffer-size: 1024 buffers-per-region: 1024 direct-buffers: true /<code>
io-threads:設置IO線程數,它主要執行非阻塞的任務,默認會取值cpu核心worker-threads:阻塞任務線程池,當執行類似servlet請求阻塞IO操作會從這個線程池中取得線程,默認值是IO線程數*8buffer-size:設置buffer大小,這些buffer會用於服務器連接的IO操作,有點類似netty的池化內存管理direct-buffers:是否分配的直接內存(NIO直接分配的堆外內存)
閱讀更多 weal1992 的文章