Spring Cloud Hystrix應用篇(十一)

1、背景

分佈式系統環境下,服務間相似依賴很是常見,一個業務調用一般依賴多個基礎服務。以下圖,對於同步調用,當庫存服務不可用時,商品服務請求線程被阻塞,當有大批量請求調用庫存服務時,最終可能致使整個商品服務資源耗盡,沒法繼續對外提供服務。而且這種不可用可能沿請求調用鏈向上傳遞,這種現象被稱爲雪崩效應。git

 

2、雪崩效應常見場景

  • 硬件故障:如服務器宕機,機房斷電,光纖被挖斷等。
  • 流量激增:如異常流量,重試加大流量等。
  • 緩存穿透:通常發生在應用重啓,全部緩存失效時,以及短期內大量緩存失效時。大量的緩存不命中,使請求直擊後端服務,形成服務提供者超負荷運行,引發服務不可用。
  • 程序BUG:如程序邏輯致使內存泄漏,JVM長時間FullGC等。
  • 同步等待:服務間採用同步調用模式,同步等待形成的資源耗盡。

3、雪崩效應應對策略

針對形成雪崩效應的不一樣場景,可使用不一樣的應對策略,沒有一種通用全部場景的策略,參考以下:github

  • 硬件故障:多機房容災、異地多活等。
  • 流量激增:服務自動擴容、流量控制(限流、關閉重試)等。
  • 緩存穿透:緩存預加載、緩存異步加載等。
  • 程序BUG:修改程序bug、及時釋放資源等。
  • 同步等待:資源隔離、MQ解耦、不可用服務調用快速失敗等。資源隔離一般指不一樣服務調用採用不一樣的線程池;不可用服務調用快速失敗通常經過熔斷器模式結合超時機制實現。

綜上所述,若是一個應用不能對來自依賴的故障進行隔離,那該應用自己就處在被拖垮的風險中。 所以,爲了構建穩定、可靠的分佈式系統,咱們的服務應當具備自我保護能力,當依賴服務不可用時,當前服務啓動自我保護功能,從而避免發生雪崩效應。本文將重點介紹使用Hystrix解決同步等待的雪崩問題。web

 4、什麼是Hystrix

在分佈式環境中,許多服務依賴項中的一些必然會失敗。Hystrix是一個庫,經過添加延遲容忍和容錯邏輯,幫助你控制這些分佈式服務之間的交互。Hystrix經過隔離服務之間的訪問點、中止級聯失敗和提供回退選項來實現這一點,全部這些均可以提升系統的總體彈性。spring

Hystrix設計目標:後端

  • 對來自依賴的延遲和故障進行防禦和控制——這些依賴一般都是經過網絡訪問的
  • 阻止故障的連鎖反應
  • 快速失敗並迅速恢復
  • 回退並優雅降級
  • 提供近實時的監控與告警

Hystrix遵循的設計原則:api

  • 防止任何單獨的依賴耗盡資源(線程)
  • 過載當即切斷並快速失敗,防止排隊
  • 儘量提供回退以保護用戶免受故障
  • 使用隔離技術(例如隔板,泳道和斷路器模式)來限制任何一個依賴的影響
  • 經過近實時的指標,監控和告警,確保故障被及時發現
  • 經過動態修改配置屬性,確保故障及時恢復
  • 防止整個依賴客戶端執行失敗,而不只僅是網絡通訊

Hystrix如何實現這些設計目標?瀏覽器

  • 使用命令模式將全部對外部服務(或依賴關係)的調用包裝在HystrixCommand或HystrixObservableCommand對象中,並將該對象放在單獨的線程中執行;
  • 每一個依賴都維護着一個線程池(或信號量),線程池被耗盡則拒絕請求(而不是讓請求排隊)。
  • 記錄請求成功,失敗,超時和線程拒絕。
  • 服務錯誤百分比超過了閾值,熔斷器開關自動打開,一段時間內中止對該服務的全部請求。
  • 請求失敗,被拒絕,超時或熔斷時執行降級邏輯。
  • 近實時地監控指標和配置的修改。

5、應用實戰

項目仍是用之前的項目,以前在spring-cloud-user寫了一個UserController,在裏面調用了spring-cloud-service服務,下面把除了spring-cloud-service外的其它服務都開啓,而後訪問接口會發現報錯,看控制檯,控制檯報的是鏈接異常,這就是一個典型的通訊失敗的案例,在生產過程當中若是訪問報一個這個頁面老是不那麼友好的,那麼怎麼解決這個通訊失敗呢。緩存

 

 

 

 

 爲了解決這個問題就引入了hystrix,在服務調用端加入Hystrix包,由於我後面每一個應用都會加入spring-cloud-api這個工程,爲了減小後面應用重複導包,我將此包放入spring-cloud-api工程,而且要在調用端加入@EnableCircuitBreaker註解服務器

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>

而後就能夠對服務進行降級和熔斷機制了,在UserController類方法中加入@HystrixCommand(fallbackMethod = "fallback")網絡

 

 

 而後再訪問瀏覽器,發現沒啥用,

 

 

 

 

 

 

這正好引出今天問題,怎麼觸發降級,剛剛配置的方法實際上是回退,降級有三種方案:

  5.一、熔斷觸發降級

       熔斷的配置信息能夠在HystrixCommandProperties類中找到,這裏我只寫3個

 

 

 而後再次發起訪問,發現發生了熔斷

 

 

 這裏有個問題,我這裏不演示了,那就是熔斷開啓以後,後續的正常請求也沒法發送過去;說完了這個下面就看下,熔斷是如何觸發的的,又是怎麼恢復的;

1.如何觸發熔斷?"判斷閾值"

     10s鍾以內,發起了20次請求,失敗率超過50%。 熔斷的恢復時間(熔斷5s)也就是說熔斷觸發了後,後續請求在5S內都不會發生到服務端 ,這就是熔斷的時間窗口說明.

2.熔斷會有一個自動恢復。

     自支恢復的概念是,5S後請求會自動試着發送到服務端,若是發現發送通訊正常了,熔斷就會成爲關閉狀態

5.二、請求超時觸發降級

        在繼續寫時要說明一個狀況那就是熔斷後超時是兩個概念,但願不要搞混了,超時是請求發送中只是時間超了閾值

 

 

 

 

 

 5.三、資源隔離觸發降級

    隔離分爲平臺隔離、部署隔離、業務隔離、 服務隔離、資源隔離;比喻說項目中的一個case,有一塊東西,是要用多線程作一些事情,小夥伴作項目的時候,沒有太留神,資源隔離,那塊代碼,在遇到一些故障的狀況下,每一個線程在跑的時候,由於那個bug,直接就死循環了,致使那塊東西啓動了大量的線程,每一個線程都死循環最終致使系統資源耗盡,崩潰,不工做,不可用,廢掉了;在系統中值得咱們隔離的資源無非就幾種:CPU、內存、線程

信號量隔離:

/**
  * 信號量隔離實現
  * 不會使用Hystrix管理的線程池處理請求。使用容器(Tomcat)的線程處理請求邏輯。
  * 不涉及線程切換,資源調度,上下文的轉換等,相對效率高。
  * 信號量隔離也會啓動熔斷機制。若是請求併發數超標,則觸發熔斷,返回fallback數據。
  * commandProperties - 命令配置,HystrixPropertiesManager中的常量或字符串來配置。
  *   execution.isolation.strategy - 隔離的種類,可選值只有THREAD(線程池隔離)和
SEMAPHORE(信號量隔離)。
  *   默認是THREAD線程池隔離。
  *   設置信號量隔離後,線程池相關配置失效。
  * execution.isolation.semaphore.maxConcurrentRequests - 信號量最大併發數。默認
值是10。常見配置500~1000。
  *   若是併發請求超過配置,其餘請求進入fallback邏輯。
  */
@HystrixCommand(fallbackMethod="semaphoreQuarantineFallback",
        commandProperties={
          @HystrixProperty(
          
 name=HystrixPropertiesManager.EXECUTION_ISOLATION_STRATEGY,
            value="SEMAPHORE"), // 信號量隔離
          @HystrixProperty(
          
 name=HystrixPropertiesManager.EXECUTION_ISOLATION_SEMAPHORE_MAX_CONCURRENT_REQU
ESTS,
            value="100") // 信號量最大併發數

線程池隔離

@HystrixCommand(groupKey="spring-cloud-service",
      commandKey = "orders",
      threadPoolKey="spring-cloud-service",
      threadPoolProperties = {
          @HystrixProperty(name = "coreSize", value = "30"),//線程池大小
          @HystrixProperty(name = "maxQueueSize", value = "100"),//最大隊列長度

          @HystrixProperty(name =  "keepAliveTimeMinutes", value ="2"),//線程存活時間

          @HystrixProperty(name = "queueSizeRejectionThreshold", value= "15")//拒絕請求

     },
      fallbackMethod = "fallback")

 

6、OpenFeign的降級策略

前面講了hystrilx的降級方法,也在以前的篇幅中講了OpenFeign的應用,下面就以hystrix爲基礎來說下在OpenFeign中是怎麼作到降級的進行對比一下,記得用OpenFeign要開啓降級和以前篇幅同樣要導入包還有在啓動類上加上

@EnableFeignClients(basePackages = "com.ghy.*")註解,另外還要在調用者的配置文件中加入下面的開啓配置
#開啓feign的支持,觸發降級的策略
feign:
  hystrix:
    enabled: true

這些搞定後,那就寫降級策略了

 

 

 訪問瀏覽器

 

 

 若是想在OpenFeign和hystrix同樣配置不少信息的話是沒辦法用註解配置的,只能在配置文件中配置,下面配置下超時的時間配置,在調用端的配置文件中配置

#開啓feign的支持,觸發降級的策略
feign:
  hystrix:
    enabled: true
hystrix:
  command:
    default:  #全局配置, feignclient#method(param)
      execution:
        timeout:
          enable: true  #超時的開啓
        isolation:
          thread:
            timeoutInMilliseconds: 3000  #設置超時時間

#設置ribbon的超時時間,並且ribbon的超時時間必定要大於hystrix,這樣才能讓hystrix生效
ribbon:
  ReadTimeout: 10000
  ConnectTimeout: 10000

 

 

 

 

 

 

 下面看下線程池隔離的配置

 

 

 

 

 

 而後建立一個spring-cloud-hystrix項目進行監控,在spring-cloud-hystrix導入如下包,而後spring-cloud-hystrix的啓動類上加上@EnableHystrixDashboard註解

      <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
        </dependency>

配置文件以下

server:
  port: 9095

eureka:
  instance:
    hostname: localhost
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/  #指向服務註冊中心的地址

訪問瀏覽器登陸到了登陸面板,被監測的服務必定要有下面的包

       <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

而且被監控的對象要配置以下配置以不斷獲取監控信息

management:
  endpoints:
    web:
      exposure:
        include: refresh,hystrix.stream

 

 

 

 由於spring-cloud-user服務的端口號是8090,在瀏覽器上訪問 http://localhost:8090/actuator/hystrix.stream能夠發如今不停的Ping咱們的服務,其實這面板的做用就是將ping的結果收集而後在面板上展現

 

 

 

在面板上輸入要監控的服務信息,若是要監控多個這面板也能作到,要作一個聚合操做

 

 

 

 

 

 

下面有三行數據,左邊第一行表示成功數,左邊第二行表示熔斷數量,左邊最後一行表示失敗數量

若是有興趣的朋友能夠下個Apache JMeter壓測工具壓測玩下,我電腦換系統了工具丟了就懶得搞了,這工具也挺簡單的

 

 

 git網址:https://github.com/ljx958720/Spring-Cloud-Hystrix.git

相關文章
相關標籤/搜索