18年底Netflix官方宣布Hystrix 已經足夠穩定,不再積極開發 Hystrix,該項目將處於維護模式。就目前來看Hystrix是比較穩定的,並且Hystrix只是停止開發新的版本,並不是完全停止維護,Bug什么的依然會維護的。因此短期內,Hystrix依然是繼續使用的。但從長遠來看,Hystrix總會達到它的生命周期的。
Hystrix的替換方案:Alibaba Sentinel、Resilience4J
Sentinel概述:
隨着微服務的流行,服務和服務之間的穩定性變得越來越重要。 Sentinel 以流量為切入點,從流量控制、熔斷降級、系統負載保護等多個維度保護服務的穩定性。
Sentinel 具有以下特征:
豐富的應用場景 :Sentinel 承接了阿里巴巴近 10 年的雙十一大促流量的核心場景,例如秒殺(即突發流量控制在系統容量可以承受的范圍)、消息削峰填谷、集群流量控制、實時熔斷下游不可用應用等。
完備的實時監控 :Sentinel 同時提供實時的監控功能。您可以在控制台中看到接入應用的單台機器秒級數據,甚至 500 台以下規模的集群的匯總運行情況。
廣泛的開源生態 :Sentinel 提供開箱即用的與其它開源框架/庫的整合模塊,例如與 SpringCloud、Dubbo、gRPC 的整合。您只需要引入相應的依賴並進行簡單的配置即可快速地接入Sentinel。
完善的 SPI 擴展點:Sentinel 提供簡單易用、完善的 SPI 擴展接口。您可以通過實現擴展接口來快速地定制邏輯。例如定制規則管理、適配動態數據源等。
Sentinel 的主要特性:
Sentinel 可以簡單的分為 Sentinel 核心庫和 Dashboard。核心庫不依賴 Dashboard,但是結合Dashboard 可以取得最好的效果。
使用 Sentinel 來進行熔斷保護,主要分為幾個步驟:
1. 定義資源
2. 定義規則
3. 檢驗規則是否生效
資源:可以是任何東西,一個服務,服務里的方法,甚至是一段代碼。
規則:Sentinel 支持以下幾種規則:流量控制規則、熔斷降級規則、系統保護規則、來源訪問控制規則和熱點參數規則。
Sentinel 的所有規則都可以在內存態中動態地查詢及修改,修改之后立即生效
先把可能需要保護的資源定義好,之后再配置規則。也可以理解為,只要有了資源,我們就可以在任何時候靈活地定義各種流量控制規則。在編碼的時候,只需要考慮這個代碼是否需要保護,如果需要保護,就將之定義為一個資源。
Sentinel組件:
管理控制台:
獲取 Sentinel 控制台 https://github.com/alibaba/Sentinel
在存放jar包的目錄,使用如下命令啟動控制台:
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-x.x.x.jar
其中 - Dserver.port=8080 用於指定 Sentinel 控制台端口為 8080 。
在瀏覽器中訪問 http://localhost:8080/ 輸入賬號密碼即可登錄
從 Sentinel 1.6.0 起,Sentinel 控制台引入基本的登錄功能,默認用戶名和密碼都是 sentinel
啟動 Sentinel 控制台需要 JDK 版本為 1.8 及以上版本。
在使用 Sentinel 控制台設置微服務各種訪問規則是存在內存中的,在微服務重啟后規則就會丟失,需要持久化保存
https://www.jianshu.com/p/609961eb6a6e
將所有的服務交給控制台管理:
客戶端接入控制台:
在客戶端(需要管理的微服務)引入坐標
客戶端需要引入 Transport 模塊來與 Sentinel 控制台進行通信。可以通過 pom.xml 引入 JAR 包:
<dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-transport-simple-http</artifactId> </dependency>
在客戶端配置啟動參數
spring:
#配置控制台的請求路徑。
cloud:
sentinel:
transport:
dashboard: localhost:8080
查看機器列表以及健康情況:訪問 http://localhost:8080/ 可看到剛才接入的客戶端
默認情況下 Sentinel 會在客戶端首次調用的時候進行初始化,開始向控制台發送心跳包。也可以配置sentinel.eager=true ,取消Sentinel控制台懶加載。
基於Sentinel的服務保護:
通用資源保護:
1.引入依賴
需要注意SpringCloud-Alibaba與SpringCloud的版本關系
父工程引入 alibaba實現的SpringCloud
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2.1.0.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency>
子工程(服務消費者)中引入 sentinel
<!-- 當引入此依賴時,前面的客戶端(對應此子工程)的sentinel-transport-simple-http就可以省略了,因為此依賴已包含了它 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency>
2.配置熔斷降級方法
/** * 訂單控制層 */ @RestController @RequestMapping("/order") public class OrderController { @Autowired private RestTemplate restTemplate; /** * 通過訂單系統,調用商品服務根據id查詢商品信息 * @param id * @return */ @GetMapping("/buy/{id}") @SentinelResource(value="order",blockHandler = "orderBlockHandler",fallback = "orderFallback") public Product findById(@PathVariable("id") Long id) { return restTemplate.getForObject("http://service-product/product/" + id, Product.class); } // 熔斷降級方法 public Product orderBlockHandler(Long id) { Product product = new Product(); product.setId(-2l); product.setProductName("觸發熔斷降級方法"); return product; } // 拋出異常降級方法 public Product orderFallback(Long id) { Product product = new Product(); product.setId(-1l); product.setProductName("觸發拋出異常降級方法"); return product; } }
在需要被保護的方法上使用 @SentinelResource 注解進行熔斷配置。與Hystrix不同的是,Sentinel對拋出異常和熔斷降級做了更加細致的區分,通過 blockHandler 指定熔斷降級方法,通過 fallback 指定觸發異常執行的降級方法。
對於@SentinelResource的其他配置如下表:
注:1.6.0 之前的版本 fallback 函數只針對降級異常( DegradeException )進行處理,不能針對業務異常進行處理
特別地,若 blockHandler 和 fallback 都進行了配置,則被限流降級而拋出 BlockException 時只會進入 blockHandler 處理邏輯。
若未配置 blockHandler 、 fallback 和 defaultFallback ,則被限流降級時會將 BlockException 直接拋出。
Feign實現熔斷:
Sentinel 適配了 Feign 組件。如果想使用,除了引入 sentinel -starter 的依賴外還需要 2 個步驟:
配置文件打開 sentinel 對 feign 的支持: feign.sentinel.enabled=true
加入 openfeign starter 依賴使 sentinel starter 中的自動化配置類生效
1.引入依賴
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
2.開啟sentinel 支持
#配置feign feign: sentinel: enabled: true
3.配置FeignClient
編寫FeignClient接口的實現類
基於Feign實現熔斷降級,需要實現自定義的ProductFeginClient接口,且實現類需要掃描到容器中(@Component),降級方法就是實現接口的方法
@Component public class ProductFeignClientImpl implements ProductFeignClient { /** * 熔斷降級的方法 * @param id * @return */ @Override public Product findById(Long id) { Product product = new Product(); product.setId(-1L); product.setProductName("熔斷,觸發降級方法"); return product; } }
修改FeignClient添加hystrix熔斷
/** * 聲明需要調用的服務名稱 * @FeignClient * name:服務提供者的服務名稱 * fallback:配置熔斷發生的降級方法實現類 */ @FeignClient(name = "service-product", fallback = ProductFeignClientImpl.class) public interface ProductFeignClient { /** * 配置需要調用的微服務接口 */ @GetMapping(value = "/product/{id}") public Product findById(@PathVariable("id") Long id); }
Feign 對應的接口中的資源名策略定義:httpmethod:protocol://requesturl。 @FeignClient 注解中的所有屬性,Sentinel 都做了兼容。
ProductFeginClient 接口中方法 findById 對應的資源名為 GET:http://service-product/product/{id},根據注冊中心最終轉成需要調用的微服務的地址
4.啟動測試
.........
注意:此工廠類必須放置在其實現接口的同級包或子包下