一、zuul併發調優
zuul默認是使用semaphore隔離,並且最大的併發默認是10
1、修改隔離策略
默認情況下推薦使用 thread 隔離策略
線程池提供了比信號量更好的隔離機制,並且從實際測試發現高吞吐場景下可以完成更多的請求。但是信號量隔離的開銷更小,對於本身就是10ms以內的系統,顯然信號量更合適
zuul:
ribbon-isolation-strategy: thread
ribbon:
threadPool:
useSeparateThreadPools: true
threadPoolKeyPrefix: api-gateway
ribbon-isolation-strategy:修改線程隔離策略useSeparateThreadPools:讓每個路由使用獨立的線程池threadPoolKeyPrefix:線程池前綴
2、Hystric熔斷器併發調優
- 我們知道Hystrix線程池的大小和超時時間我們都是可以設置的,線上環境,我們需要對這些參數進行調整,該如何調整呢?
- 假設你的系統B,預計QPS是30,每秒請求響應時間是200ms,那麼可以算出30*0.2=6,然後再加點緩衝空間,比如4,那麼總共就是6+4=10的線程數量,當然這個4你可以自己調整,這是爲了防止突然增大的流量給個緩衝的餘地
- 當然這個緩存增加的線程數量對設置超時時間是有參考意義的,比如上面我如果設置了10條線程,此時的超時時間該設置多少?並不是越多越好哦,應該是這麼算:10/30=0.333,那麼也就是在300ms左右,10是線程池數目,30是你預計的QPS。
- 想象下,如果超時時間設爲500ms,當很多請求都變爲500ms時,也就是10/0.5=20,你的QPS變成了20,那麼多餘的請求就不會不斷堆積,導致線程卡死,線程卡死後的恢復速度會是比較慢的,所以要合理設置線程池和超時時間。
修改熔斷器的線程數量,注意線程數不是越多越好
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 #默認值200
max-connections-per-route: 100 #默認值50
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)
四、JVM參數調優
關於Jvm調優Oracle官網有一份指導說明:
Oracle官網對Jvm調優的說明
有興趣大家可以去看看。
執行啓動設置Jvm參數的操作。
java -Xms1024m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m -Xmn256m -Xss256k -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC -jar test-1.0.0.jar
關於這些設置的JVM參數是什麼意思,請參考第二步中的oracle官方給出的調優文檔。我在這邊簡單說一下:
-XX:MetaspaceSize=128m (元空間默認大小)
-XX:MaxMetaspaceSize=128m (元空間最大大小)
-Xms1024m (堆最大大小)
-Xmx1024m (堆默認大小)
-Xmn256m (新生代大小)
-Xss256k (棧最大深度大小)
-XX:SurvivorRatio=8 (新生代分區比例 8:2)
-XX:+UseConcMarkSweepGC (指定使用的垃圾收集器,這裏使用CMS收集器)
-XX:+PrintGCDetails (打印詳細的GC日誌)