分佈式系統環境下,服務間相似依賴很是常見,一個業務調用一般依賴多個基礎服務。以下圖,對於同步調用,當庫存服務不可用時,商品服務請求線程被阻塞,當有大批量請求調用庫存服務時,最終可能致使整個商品服務資源耗盡,沒法繼續對外提供服務。而且這種不可用可能沿請求調用鏈向上傳遞,這種現象被稱爲雪崩效應。git
針對形成雪崩效應的不一樣場景,可使用不一樣的應對策略,沒有一種通用全部場景的策略,參考以下:github
綜上所述,若是一個應用不能對來自依賴的故障進行隔離,那該應用自己就處在被拖垮的風險中。 所以,爲了構建穩定、可靠的分佈式系統,咱們的服務應當具備自我保護能力,當依賴服務不可用時,當前服務啓動自我保護功能,從而避免發生雪崩效應。本文將重點介紹使用Hystrix解決同步等待的雪崩問題。web
在分佈式環境中,許多服務依賴項中的一些必然會失敗。Hystrix是一個庫,經過添加延遲容忍和容錯邏輯,幫助你控制這些分佈式服務之間的交互。Hystrix經過隔離服務之間的訪問點、中止級聯失敗和提供回退選項來實現這一點,全部這些均可以提升系統的總體彈性。spring
Hystrix設計目標:後端
Hystrix遵循的設計原則:api
Hystrix如何實現這些設計目標?瀏覽器
項目仍是用之前的項目,以前在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")網絡
而後再訪問瀏覽器,發現沒啥用,
這正好引出今天問題,怎麼觸發降級,剛剛配置的方法實際上是回退,降級有三種方案:
熔斷的配置信息能夠在HystrixCommandProperties類中找到,這裏我只寫3個
而後再次發起訪問,發現發生了熔斷
這裏有個問題,我這裏不演示了,那就是熔斷開啓以後,後續的正常請求也沒法發送過去;說完了這個下面就看下,熔斷是如何觸發的的,又是怎麼恢復的;
1.如何觸發熔斷?"判斷閾值"
10s鍾以內,發起了20次請求,失敗率超過50%。 熔斷的恢復時間(熔斷5s)也就是說熔斷觸發了後,後續請求在5S內都不會發生到服務端 ,這就是熔斷的時間窗口說明.
2.熔斷會有一個自動恢復。
自支恢復的概念是,5S後請求會自動試着發送到服務端,若是發現發送通訊正常了,熔斷就會成爲關閉狀態
在繼續寫時要說明一個狀況那就是熔斷後超時是兩個概念,但願不要搞混了,超時是請求發送中只是時間超了閾值
隔離分爲平臺隔離、部署隔離、業務隔離、 服務隔離、資源隔離;比喻說項目中的一個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")
前面講了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壓測工具壓測玩下,我電腦換系統了工具丟了就懶得搞了,這工具也挺簡單的