Spring Cloud常見問題與總結(三)
一.Spring Cloud各元件重試
Spring Cloud各元件的重試配置。
早期,Spring Cloud的重試機制是比較混亂的-各個元件都有自己的重試機制,例如Ribbon、Feign、Zuul。官方也意識到了這個問題,並對重試相關邏輯進行了改造與簡化。
在Spring Cloud Edgware中,配置重試是非常簡單的。
重試步驟
1.重試依賴spring-retry,因此引入重試依賴
<dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> </dependency>
2.配置重試
<client>
ribbon:
# 同一例項最大重試次數,不包括首次呼叫
MaxAutoRetries: 1
# 重試其他例項的最大重試次數,不包括首次所選的server
MaxAutoRetriesNextServer: 2
# 是否所有操作都進行重試
OkToRetryOnAllOperations: false
其中<client>是Ribbon Client名稱,表示對指定名稱的Ribbon Client進行重試。如果省略,則表示對所有Ribbon Client都進行重試。
3.對於Zuul,重試特性預設關閉。可使用zuul.retryable=true全域性開啟重試,也可使用zuul.routes.<routename>.retryable=true開啟指定<routename>重試。
基於HTTP響應碼重試
Spring Cloud也支援基於HTTP響應碼進行重試,只需使用類似如下的配置即可:
<clientName>:
ribbon:
retryableStatusCodes: 404,502
關閉重試
1.對於其它元件,可配置spring.cloud.loadbalancer.retry.enabled=false.
2.對於zuul,可配置zuul.retryable=false或zuul.routes.<routename>.retryable=true.
注意點
- Hystrix的超時時間必須大於超時的時間,否則,一旦Hystrix超時,就沒辦法繼續重試了。
- 一般來說,不建議將
ribbon.OkToRetryOnAllOperations
設為true。因為一旦啟用該配置,則表示重試任何操作,包括POST請求,而由於快取了請求體,此時可能會影響伺服器的資源。
參考文件
二.Spring Cloud各元件調優
Spring Cloud各元件的調優配置。
注:只討論元件本身的優化配置,不討論JVM引數配置。
1.Tomcat引數
Spring Boot預設內嵌了Tomcat。因此,可對Tomcat的併發引數進行優化。
server:
tomcat:
max-connections: <最大連線數>
max-threads: <最大執行緒數>
min-spare-threads: <最小空閒執行緒數>
accept-count: <當tomcat啟動的執行緒數達到最大時,接收排隊請求數>
Spring Boot也支援使用Jetty或Undertow來替代tomcat,具體可看https://docs.spring.io/spring-boot/docs/1.5.9.RELEASE/reference/htmlsingle/#common-application-properties。
2.Hystrix引數
若隔離策略是THREAD則引數為:
hystrix.threadpool.<HystrixThreadPoolKey>.coreSize: 10
hystrix.threadpool.<HystrixThreadPoolKey>.maximumSize: 10
hystrix.threadpool.<HystrixThreadPoolKey>.maxQueueSize: -1 # 如該值為-1,那麼使用的是SynchronousQueue,否則使用的是LinkedBlockingQueue。注意,修改MQ的型別需要重啟。例如從-1修改為100,需要重啟,因為使用的Queue型別發生了變化
若將HystrixThreadPoolKey改為default,則表示通用配置。
若隔離策略是SEMAPHORE則引數為:
hystrix.command.<HystrixThreadPoolKey>.execution.isolation.strategy: SEMAPHORE
hystrix.command.<HystrixThreadPoolKey>.execution.isolation.semaphore.maxConcurrentRequests: 10 # 預設值
若將HystrixThreadPoolKey改為default,則表示通用配置。
3.Feign引數
Feign預設使用JDK原聲的URLConnection傳送HTTP請求,沒有連線池。在實際專案中,我們往往希望使用執行緒池來管理HTTP。要想使用執行緒池,需使用Apache HttpClient或OKHttp。
當使用Apache HttpClient,可配置連線數等資訊:
feign:
httpclient:
enabled: true
max-connections: 200 # 預設值
max-connections-per-route: 50 # 預設值
程式碼詳見:
org.springframework.cloud.netflix.feign.FeignAutoConfiguration.HttpClientFeignConfiguration#connectionManager
org.springframework.cloud.netflix.feign.ribbon.HttpClientFeignLoadBalancedConfiguration.HttpClientFeignConfiguration#connectionManager
當使用OKHttp時,可如下設定:
feign:
okhttp:
enabled: true
httpclient:
max-connections: 200 # 預設值
max-connections-per-route: 50 # 預設值
程式碼詳見:
org.springframework.cloud.netflix.feign.FeignAutoConfiguration.OkHttpFeignConfiguration#httpClientConnectionPool
。org.springframework.cloud.netflix.feign.ribbon.OkHttpFeignLoadBalancedConfiguration.OkHttpFeignConfiguration#httpClientConnectionPool
。
4.zuul引數
我們知道Hystrix有隔離策略:THREAD
以及SEMAPHORE
,預設是 SEMAPHORE
。
當Zuul的隔離策略為SEMAPHORE,此時可進行如下設定。
設定預設最大訊號量:
zuul:
semaphore:
max-semaphores: 100 # 預設值
設定指定服務的最大訊號量:
zuul:
eureka:
<commandKey>:
semaphore:
max-semaphores: 100 # 預設值
參考:
- https://github.com/spring-cloud/spring-cloud-netflix/issues/1130
- https://github.com/spring-cloud/spring-cloud-netflix/issues/1362 ,非常重要,裡面指出,不同版本配置略有差異。
<commandKey>
在Brixton.SR5及更早版本中,是<serviceId>RibbonCommand
,從Brixton.SR6
開始,<commandKey>
只需寫<serviceId>
即可,即:服務註冊到Eureka Server上的名稱。
當Zuul的隔離策略為Thread(
zuul:
ribbon-isolation-strategy: thread
)時,首先,在Edgware及更高版本中,Zuul支援為微服務設定獨立的Hystrix執行緒池
參考:http://www.itmuch.com/spring-cloud/edgware-new-zuul-hystrix-thread-pool/
zuul:
threadPool:
useSeparateThreadPools: true
除此之外,還可以使用如下配置進行調優。
- 對於執行SimpleHostRoutingFilter過濾器的路由,可將路由配置如下:
zuul:
routes:
user-route: # 該配置方式中,user-route只是給路由一個名稱,可以任意起名。
url: http://localhost:8000/ # 指定的url
path: /user/** # url對應的路徑。
可使用如下屬性配置併發引數:
zuul:
host:
max-total-connections: 200 # 預設值
max-per-route-connections: 20 # 預設值
- 對於執行RibbonRoutingFilter的路由,可使用如下屬性配置併發引數:
<service-Id>: ribbon: MaxTotalConnections: 0 # 預設值 MaxConnectionsPerHost: 0 # 預設值
相關程式碼:
org.springframework.cloud.netflix.ribbon.apache.HttpClientRibbonConfiguration
關閉過濾器
Zuul大多數功能都是基於過濾器是實現的。因此,如果一些過濾器使用不到,可考慮關閉,特別是,目前一些過濾器的實現並不高效。
例如FormBodyWrapperFilter,目前內部是通過加同步鎖的方式實現的,效能較低。因此,如果你的微服務不包含Form表單,完全可以關閉該過濾器,以獲取最大效能。
更多精彩內容,請掃我有驚喜。