1. 程式人生 > >Spring Cloud常見問題與總結(三)

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請求,而由於快取了請求體,此時可能會影響伺服器的資源。

參考文件

http://cloud.spring.io/spring-cloud-static/Edgware.RELEASE/single/spring-cloud.html#retrying-failed-requests

 

二.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 # 預設值

參考:

當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表單,完全可以關閉該過濾器,以獲取最大效能。

更多精彩內容,請掃我有驚喜。