一 、Ribbon概述
Netflixfa 發布的一個負載均衡器,有助于控制HTTP和TCP客戶端行為,在SpringCloud中,Ribbon提供了客戶端負載均衡的功能,Ribbon自動從服務注冊中心Eureka中讀取到的服務提供者的串列資訊(動態獲取服務串列方式),在呼叫服務節點提供的服務時,基于內置的負載均衡演算法,合理進行負載,
1、Ribbon的主要作用
(1)服務呼叫 基于Ribbon實作服務呼叫, 是通過拉取到的所有服務串列組成(服務名-請求路徑的)映射關系,借助RestTemplate最終進行呼叫;
(2)負載均衡 當有多個服務提供者時,Ribbon可以根據負載均衡的演算法自動的選擇需要呼叫的服務地址,
2、服務呼叫Ribbon高級
(1)負載均衡概述
在搭建網站時,如果單節點的 web服務性能和可靠性都無法達到要求;或者是在使用外網服務時,經常擔心被人攻破,一不小心就會有打開外網埠的情況,通常這個時候加入負載均衡就能有效解決服務問題, 負載均衡是一種基礎的網路服務,其原理是通過運行在前面的負載均衡服務,按照指定的負載均衡演算法,將流量分配到后端服務集群上,從而為系統提供并行擴展的能力, 負載均衡的應用場景包括流量包、轉發規則以及后端服務,由于該服務有內外網個例、健康檢查等功 能,能夠有效提供系統的安全性和可用性,

(2) 客戶端負載均衡與服務端負載均衡
服務端負載均衡:先發送請求到負載均衡服務器或者軟體,然后通過負載均衡演算法,在多個服務器之間選擇一個進行訪 問;即在服務器端再進行負載均衡演算法分配,
客戶端負載均衡:客戶端會有一個服務器地址串列,在發送請求前通過負載均衡演算法選擇一個服務器,然后進行訪問,這是客戶端負載均衡;即在客戶端就進行負載均衡演算法分配,
3、Feign簡介
Feign是Netflix開發的宣告式,模板化的HTTP客戶端,其靈感來自Retrofit、JAXRS-2.0以及WebSocket. Feign可幫助我們更加便捷、優雅的呼叫HTTP API, 在SpringCloud中,使用Feign非常簡單, Feign支持多種注解,例如Feign自帶的注解或者JAX-RS注解等, SpringCloud對Feign進行了增強,使Feign支持了SpringMVC注解,并整合了Ribbon和Eureka, 從而讓Feign的使用更加方便,
3.1 基于Feign的服務呼叫
(1)引入依賴 在服務消費者 shop_service_order 添加Fegin依賴
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
(2)啟動類添加Feign的支持
@SpringBootApplication(scanBasePackages="cn.itcast.order") @EntityScan("cn.itcast.entity") @EnableFeignClients public class OrderApplication { public static void main(String[] args) { SpringApplication.run(OrderApplication.class, args); } }
通過@EnableFeignClients注解開啟Spring Cloud Feign的支持功能
(3)啟動類激活FeignClient
創建一個Feign介面,此介面是在Feign中呼叫微服務的核心介面 在服務消費者 shop_service_order 添加一個 ProductFeginClient 介面
//指定需要呼叫的微服務名稱 @FeignClient(name="shop-service-product") public interface ProductFeginClient { //呼叫的請求路徑 @RequestMapping(value = "https://www.cnblogs.com/product/{id}",method = RequestMethod.GET) public Product findById(@PathVariable("id") Long id); }
定義各引數系結時,@PathVariable、@RequestParam、@RequestHeader等可以指定引數屬性,在Feign中系結引數必須通過value屬性來指明具體的引數名,不然會拋出例外 @FeignClient:注解通過name指定需要呼叫的微服務的名稱,用于創建Ribbon的負載均衡器, 所以Ribbon會把shop-service-product決議為注冊中心的服務,
3.2 Feign和Ribbon的聯系
Ribbon是一個基于HTTP和TCP客戶端的負載均衡的工具,可以在客戶端配置 RibbonServerList(服務端串列),使用 HttpClient 或 RestTemplate 模擬http請求,步驟相當繁瑣,
Feign是在Ribbon的基礎上進行了一次改進,是一個使用起來更加方便的HTTP客戶端,采用介面的方式,只需要創建一個介面,然后在上面添加注解即可,將需要呼叫的其他服務的方法定義成抽象方法即可,不需要自己構建http請求,然后就像是呼叫自身工程的方法呼叫,而感覺不到是呼叫遠程方法,使得撰寫客戶端變得非常容易,
3.3 負載均衡
Feign中本身已經集成了Ribbon依賴和自動配置,因此我們不需要額外引入依賴,也不需要再注冊 RestTemplate 物件,
二、服務熔斷Hystrix入門
1、服務容錯的核心知識
(1)雪崩效應
在微服務架構中,一個請求需要呼叫多個服務是非常常見的,如客戶端訪問A服務,而A服務需要呼叫B服務,B服務需要呼叫C服務,由于網路原因或者自身的原因,如果B服務或者C服務不能及時回應,A服務將處于阻塞狀態,直到B服務C服務回應,此時若有大量的請求涌入,容器的執行緒資源會被消耗完畢, 導致服務癱瘓,服務與服務之間的依賴性,故障會傳播,造成連鎖反應,會對整個微服務系統造成災難 性的嚴重后果,這就是服務故障的“雪崩”效應,
雪崩是系統中的蝴蝶效應導致其發生的原因多種多樣,有不合理的容量設計,或者是高并發下某一個方 法回應變慢,亦或是某臺機器的資源耗盡,從源頭上我們無法完全杜絕雪崩源頭的發生,但是雪崩的根本原因來源于服務之間的強依賴,所以我們可以提前評估,做好熔斷、隔離、限流,
(2) 服務隔離
顧名思義,它是指將系統按照一定的原則劃分為若干個服務模塊,各個模塊之間相對獨立,無強依賴, 當有故障發生時,能將問題和影響隔離在某個模塊內部,而不擴散風險,不波及其它模塊,不影響整體的系統服務,
(3)熔斷降級
在互聯網系統中,當下游服務因訪問壓力過大而回應變慢或失敗,上游服務為了保護系統整體的可用性,可以暫時切斷對下游服務的呼叫,這種犧牲區域,保全整體的措施就叫做熔斷,
所謂降級,就是當某個服務熔斷之后,服務器將不再被呼叫,此時客戶端可以自己準備一個本地的 fallback回呼,回傳一個預設值,
(4)服務限流
限流可以認為服務降級的一種,限流就是限制系統的輸入和輸出流量已達到保護系統的目的,一般來說系統的吞吐量是可以被測算的,為了保證系統的穩固運行,一旦達到的需要限制的閾值,就需要限制流 量并采取少量措施以完成限制流量的目的,比如:推遲解決,拒絕解決,或者部分拒絕解決等等,
2、Hystrix介紹
Hystrix是由Netflix開源的一個延遲和容錯庫,用于隔離訪問遠程系統、服務或者第三方庫,防止級聯失敗,從而提升系統的可用性與容錯性,Hystrix主要通過以下幾點實作延遲和容錯,
包裹請求:使用HystrixCommand包裹對依賴的呼叫邏輯,每個命令在獨立執行緒中執行,這使用了設計模式中的“命令模式”,
跳閘機制:當某服務的錯誤率超過一定的閾值時,Hystrix可以自動或手動跳閘,停止請求該服務一段時間,
資源隔離:Hystrix為每個依賴都維護了一個小型的執行緒池(或者信號量),如果該執行緒池已滿, 發往該依賴的請求就被立即拒絕,而不是排隊等待,從而加速失敗判定,
監控:Hystrix可以近乎實時地監控運行指標和配置的變化,例如成功、失敗、超時、以及被拒絕 的請求等,
回退機制:當請求失敗、超時、被拒絕,或當斷路器打開時,執行回退邏輯,回退邏輯由開發人員自行提供,例如回傳一個預設值,
自我修復:斷路器打開一段時間后,會自動進入“半開”狀態,
3、 Rest實作服務熔斷
(2)配置依賴
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>
(3)開啟熔斷
在啟動類 OrderApplication 中添加 @EnableCircuitBreaker 注解開啟對熔斷器的支持,
@EntityScan("cn.itcast.entity")
//@EnableCircuitBreaker //開啟熔斷器
//@SpringBootApplication
@SpringCloudApplication public class OrderApplication { //創建RestTemplate物件 @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(OrderApplication.class, args); } }
可以看到,我們類上的注解越來越多,在微服務中,經常會引入上面的三個注解,于是Spring就提供了 一個組合注解:@SpringCloudApplication
4)配置熔斷降級業務邏輯
@RestController @RequestMapping("/order") public class OrderController { @Autowired private RestTemplate restTemplate; //下訂單 @GetMapping("/product/{id}") @HystrixCommand(fallbackMethod = "orderFallBack") public Product findProduct(@PathVariable Long id) { return restTemplate.getForObject("http://shop-serviceproduct/product/1", Product.class); } //降級方法 public Product orderFallBack(Long id) { Product product = new Product(); product.setId(-1l); product.setProductName("熔斷:觸發降級方法"); return product; } }
為 findProduct方法撰寫一個回退方法findProductFallBack,該方法與 findProduct 方法具有相同的引數與回傳值型別,該方法回傳一個默認的錯誤資訊, 在 Product 方法上,使用注解@HystrixCommand的fallbackMethod屬性,指定熔斷觸發的降級方法是findProductFallBack ,因為熔斷的降級邏輯方法必須跟正常邏輯方法保證相同的引數串列和回傳值宣告,在findProduct 方法上HystrixCommand(fallbackMethod = "findProductFallBack") 用來宣告一個降級邏輯的方法,
4、斷路器聚合監控Turbine
在微服務架構體系中,每個服務都需要配置Hystrix DashBoard監控,如果每次只能查看單個實體的監控資料,就需要不斷切換監控地址,這顯然很不方便,要想看這個系統的Hystrix Dashboard資料就需要用到Hystrix Turbine,Turbine是一個聚合Hystrix 監控資料的工具,它可以將所有相關微服務的 Hystrix 監控資料聚合到一起,方便使用,引入Turbine后,整個監控系統架構如下:

(1) 搭建TurbineServer 創建工程 shop_hystrix_turbine 引入相關坐標
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-turbine</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId> </dependency>
(2) 配置多個微服務的hystrix監控 在application.yml的組態檔中開啟turbine并進行相關配置
server:
port: 8031
spring:
application:
name: microservice-hystrix-turbine
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
turbine:
# 要監控的微服務串列,多個用,分隔
appConfig: shop-service-order
clusterNameExpression: "'default'"
eureka相關配置 : 指定注冊中心地址
turbine相關配置:指定需要監控的微服務串列
turbine會自動的從注冊中心中獲取需要監控的微服務,并聚合所有微服務中的 /hystrix.stream 資料
(3)配置啟動類
@SpringBootApplication @EnableTurbine @EnableHystrixDashboard public class TurbineServerApplication { public static void main(String[] args) { SpringApplication.run(TurbineServerApplication.class, args); } }
作為一個獨立的監控專案,需要配置啟動類,開啟HystrixDashboard監控平臺,并激活Turbine
5、熔斷器的狀態
熔斷器有三個狀態 CLOSED 、 OPEN 、 HALF_OPEN 熔斷器默認關閉狀態,當觸發熔斷后狀態變更為 OPEN ,在等待到指定的時間,Hystrix會放請求檢測服務是否開啟,這期間熔斷器會變為 HALF_OPEN 半 開啟狀態,熔斷探測服務可用則繼續變更為 CLOSED 關閉熔斷器,

Closed:關閉狀態(斷路器關閉),所有請求都正常訪問,代理類維護了最近呼叫失敗的次數, 如果某次呼叫失敗,則使失敗次數加1,如果最近失敗次數超過了在給定時間內允許失敗的閾值, 則代理類切換到斷開(Open)狀態,此時代理開啟了一個超時時鐘,當該時鐘超過了該時間,則切換到半斷開(Half-Open)狀態,該超時時間的設定是給了系統一次機會來修正導致呼叫失敗的錯誤,
Open:打開狀態(斷路器打開),所有請求都會被降級,Hystix會對請求情況計數,當一定時間 內失敗請求百分比達到閾值,則觸發熔斷,斷路器會完全關閉,默認失敗比例的閾值是50%,請求 次數最少不低于20次,
Half Open:半開狀態,open狀態不是永久的,打開后會進入休眠時間(默認是5S),隨后斷路 器會自動進入半開狀態,此時會釋放1次請求通過,若這個請求是健康的,則會關閉斷路器,否則 繼續保持打開,再次進行5秒休眠計時,
熔斷器的默認觸發閾值是20次請求,不好觸發,休眠時間時5秒,時間太短,不易觀察,為了測驗方便,我們可以通過配置修改熔斷策略:
circuitBreaker.requestVolumeThreshold=5
circuitBreaker.sleepWindowInMilliseconds=10000
circuitBreaker.errorThresholdPercentage=50
requestVolumeThreshold:觸發熔斷的最小請求次數,默認20
errorThresholdPercentage:觸發熔斷的失敗請求最小占比,默認50%
sleepWindowInMilliseconds:熔斷多少秒后去嘗試請求
6、熔斷器的隔離策略
微服務使用Hystrix熔斷器實作了服務的自動降級,讓微服務具備自我保護的能力,提升了系統的穩定性,也較好的解決雪崩效應,其使用方式目前支持兩種策略:
(1)執行緒池隔離策略:使用一個執行緒池來存盤當前的請求,執行緒池對請求作處理,設定任務回傳處理超時時間,堆積的請求堆積入執行緒池佇列,這種方式需要為每個依賴的服務申請執行緒池,有一定的資源消耗,好處是可以應對突發流量(流量洪峰來臨時,處理不完可將資料存盤到執行緒池隊里慢慢處理),
(2)信號量隔離策略:使用一個原子計數器(或信號量)來記錄當前有多少個執行緒在運行,請求來先判斷計數器的數值,若超過設定的最大執行緒個數則丟棄該型別的新請求,若不超過則執行計數操作請求來計數器+1,請求回傳計數器-1,這種方式是嚴格的控制執行緒且立即回傳模式,無法應對突發流量(流量洪峰來臨時,處理的執行緒超過數量,其他的請求會直接回傳,不繼續去請求依賴的服務),
執行緒池和型號量兩種策略功能支持對比如下:

hystrix.command.default.execution.isolation.strategy : 配置隔離策略
ExecutionIsolationStrategy.SEMAPHORE 信號量隔離
ExecutionIsolationStrategy.THREAD 執行緒池隔離
hystrix.command.default.execution.isolation.maxConcurrentRequests : 最大信號量上限
7、Hystrix的核心原始碼
Hystrix 底層基于 RxJava,RxJava 是回應式編程開發庫,因此Hystrix的整個實作策略簡單說即:把一個HystrixCommand封裝成一個Observable(待觀察者),針對自身要實作的核心功能,對Observable進行各種裝飾,并在訂閱各步裝飾的Observable,以便在指定事件到達時,添加自己的業務,

Hystrix主要有4種呼叫方式:
toObservable() 方法 :未做訂閱,只是回傳一個Observable ;
observe() 方法 :呼叫 #toObservable() 方法,并向 Observable 注冊 rx.subjects.ReplaySubject 發起訂閱;
queue() 方法 :呼叫 #toObservable() 方法的基礎上,呼叫:Observable#toBlocking() 和 BlockingObservable#toFuture() 回傳 Future 物件;
execute() 方法 :呼叫 #queue() 方法的基礎上,呼叫 Future#get() 方法,同步回傳 #run() 的執行結果,
主要的執行邏輯:
1). 每次呼叫創建一個新的HystrixCommand,把依賴呼叫封裝在run()方法中.
2). 執行execute()/queue做同步或異步呼叫.
3). 判斷熔斷器(circuit-breaker)是否打開,如果打開跳到步驟8,進行降級策略,如果關閉進入步驟4
4). 判斷執行緒池/佇列/信號量是否跑滿,如果跑滿進入降級步驟8,否則繼續后續步驟5
5). 呼叫HystrixCommand的run方法.運行依賴邏輯,依賴邏輯呼叫超時,執行步驟6
6). 判斷邏輯是否呼叫成功,回傳成功呼叫結果;呼叫出錯,執行步驟7
7). 計算熔斷器狀態,所有的運行狀態(成功, 失敗, 拒絕,超時)上報給熔斷器,用于統計從而判斷熔斷器狀態.
8). getFallback()降級邏輯,
以下四種情況將觸發getFallback呼叫:
1). run()方法拋出非HystrixBadRequestException例外,
2). run()方法呼叫超時
3). 熔斷器開啟攔截呼叫
4). 執行緒池/佇列/信號量是否跑滿
5). 沒有實作getFallback的Command將直接拋出例外,fallback降級邏輯呼叫成功直接回傳,降 級邏輯呼叫失敗拋出例外.
9). 回傳執行成功結果
8、請求合并
Hystrix支持將多個請求自動合并為一個請求,通過合并可以減少HystrixCommand并發執行所需的執行緒和網路連接數量,極大地節省了開銷,提高了系統效率,請求合并是由Hystrix自動合并進行的,并不需要在開發時進行代碼介入(注意,這里只是說合并請求不需要代碼介入,但對于批量請求的處理,還是需要寫一些代碼的),需要注意的是,多個請求能自動合并的前提是請求之間要足夠“近”,即執行的間隔時長要足夠小(默認為10ms,可通過hystrix.collapser.default.timerDelayInMilliseconds進行設定),即執行間隔超過10ms的請求不會合并執行,
如果沒有啟用請求合并,那么在HystrixCommand執行的執行緒池和后端業務執行中都會存在大量的并發,很可能會造成性能瓶頸,另外,如果要讓Hystrix能夠使用到請求合并,那么業務代碼必須提供能夠批量處理的介面,
9、服務熔斷Hystrix的替換方案
18年底Netflix官方宣布Hystrix 已經足夠穩定,不再積極開發 Hystrix,該專案將處于維護模式,就目前來看Hystrix是比較穩定的,并且Hystrix只是停止開發新的版本,并不是完全停止維護,Bug什么的依然會維護的,因此短期內,Hystrix依然是繼續使用的,但從長遠來看,Hystrix總會達到它的生命周期,
(1)替換方案介紹
Alibaba Sentinel
Sentinel 是阿里巴巴開源的一款斷路器實作,目前在Spring Cloud的范訓器專案Spring Cloud Alibaba 中的一員Sentinel本身在阿里內部已經被大規模采用,非常穩定,因此可以作為一個較好的替代品,
Resilience4J
Resilicence4J 一款非常輕量、簡單,并且檔案非常清晰、豐富的熔斷工具,這也是Hystrix官方推薦的替代產品,不僅如此,Resilicence4j還原生支持Spring Boot 1.x/2.x,而且監控也不像Hystrix一樣弄 Dashboard/Hystrix等一堆輪子,而是支持和Micrometer(Pivotal開源的監控門面,Spring Boot 2.x 中的Actuator就是基于Micrometer的)、prometheus(開源監控系統,來自谷歌的論文)、以及 Dropwizard metrics(Spring Boot曾經的模仿物件,類似于Spring Boot)進行整合,
(1.1) Sentinel概述
Sentinel 以流量為切入點,從流量控制、熔斷降級、系統負載保護等多個維度保護服務的穩定性,
Sentinel 具有以下特征:
豐富的應用場景:Sentinel 承接了阿里巴巴近 10 年的雙十一大促流量的核心場景,例如秒殺(即 突發流量控制在系統容量可以承受的范圍)、訊息削峰填谷、集群流量控制、實時熔斷下游不可用 應用等,
完備的實時監控:Sentinel 同時提供實時的監控功能,可以在控制臺中看到接入應用的單臺機器秒級資料,甚至 500 臺以下規模的集群的匯總運行情況,
廣泛的開源生態:Sentinel 提供開箱即用的與其它開源框架/庫的整合模塊,例如與 Spring Cloud、Dubbo、gRPC 的整合,您只需要引入相應的依賴并進行簡單的配置即可快速地接入 Sentinel, 完善的SPI擴展點:Sentinel 提供簡單易用、完善的 SPI 擴展介面,可以通過實作擴展介面來快速地定制邏輯,例如定制規則管理、適配動態資料源等,
Sentinel 的主要特性:

(1.2) Sentinel與Hystrix的區別

(1.3) 遷移方案
Sentinel官方提供了詳細的由Hystrix 遷移到Sentinel 的方法

感謝閱讀,借鑒了不少大佬資料,如需轉載,請注明出處,謝謝!https://www.cnblogs.com/huyangshu-fs/p/13882618.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/509544.html
標籤:其他
上一篇:初識設計模式 - 原型模式
