唯能極於情,故能極於劍
文:SpringCloud(四)- Hystris簡介及@EnableCircuitBreaker 和 @HystrixCommand 注解的使用
注:有空看看小編:CodeCow · 程序牛
的個人技術博客吧:http://www.codecow.cn/
《 人生路上,你我都是過客,來去皆是緣分 —— 隨緣 》
問題:
1、復雜的分布式體系結構中,每個應用程序都有數十個依賴,每個依賴關系在某些時候將不可避免的失敗;此時怎么辦?
2、當服務之間的調用時,出現網絡卡頓、超時、程序出錯、甚至機房斷電,此時又怎么辦 ?
3、直接上圖
這可咋辦,涼拌,哈哈,不可能,此時迎來了我們的 “豪豬哥 — Hystris ” 帶着這兩個問題,小編將淺聊 Hystris
一、Hystris
- 官網:Hystris 是一個處理分布式系統的 延遲 和 容錯 的開源庫,在服務調用中不可避免的會調用失敗,比如超時、異常等,Hystris 能夠保證在一個服務出問題的情況下,不會導致整體服務失敗,避免級聯故障,以提高分布式系統的彈性
①、服務降級(fallback)
例如:當服務器超時、程序運行異常、線程池爆滿的時候,立即返回一個友好提示如 “服務器忙,請稍后再試”,而不是直接給客服端整個 ERROR
②、服務熔斷(break)
例如:當服務器達到最大訪問量后,直接拒絕訪問(例如家里的 保險絲 ),然后調用服務降級的方法並返回友好提示(過程:服務降級 —> 進而熔斷 —> 恢復調用鏈路 )
③、服務限流(flowlimit)
例如:淘寶、京東秒殺時高並發操作時,嚴禁一窩蜂的過來擁擠,大家排隊,一秒N個,有序進行
。。。。。。
官網:https://github.com/Netflix/Hystrix/wiki/How-To-Use

呵呵,朋友別着急,下面小編帶你細品 豪豬哥
二、Hystris 實操
了解 Hystris 了,不來點 硬核 咋行呢,下面小編就結合實際開發和大家聊聊
注意:有服務端和客戶端兩個模塊/項目
①、首先導包
// 監控 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> // Web <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> // 服務注冊與發現 Consul <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-consul-discovery</artifactId> </dependency> // 熔斷器 Hystris <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>
②、改 YML 配置文件
server: port: 8888 #端口號 spring: application: name: cloud-hystrix-provider-service #服務名 cloud: consul: host: localhost #consul的IP port: 8500 #consul啟動端口默認8500 discovery: service-name: ${spring.application.name} prefer-ip-address: true #不寫這個配置,在docker下的consul里面健康檢查會失敗 healthCheckInterval: 5s #健康檢查頻率 port: ${server.port} #注冊服務所在端口
③、添加主啟動類
/** * 注意:@SpringCloudApplication 注解可以代替下面三個注解 */ @SpringBootApplication // springboot 注解 @EnableDiscoveryClient // 作用:能夠讓Consul注冊中心發現,並掃描到該服務 @EnableCircuitBreaker // SpringCloud中使用斷路器,需要加上此注解 public class HystrixProviderMain8001 { public static void main(String[] args) { SpringApplication.run(HystrixProviderMain8001.class, args); } }
④、業務邏輯Controller
@Resource private PaymentService paymentService; //service層調用 @GetMapping("/payment/hystrix/ok/{id}") public RespResult<Payment> getPaymentById(@PathVariable("id") Integer id) { log.info(" hystrix 8001 ok "); //使用@Slf4j打印日志 Payment payment = paymentService.getById(id); //getById 是serviceImpl中根據id 獲取 payment 實體的方法, 小編在這就不贅述了 if(payment == null){ return new RespResult<>(444, "查詢為空"); } return RespResult.success(payment); } 解釋 :Payment 實體就兩個字段 id、desc RespResult {"code":200,"message":"成功","data":{"id":1,"desc":"我還是從前那個少年"}} 這種格式 經過 小編一頓 SAO 操作, 服務端 還可以吧 ^ _ ^ 別急 沒完事的 。。。。
2.2、客服端 / 消費端 – 操作
注意:消費端大體和客服端一樣,注意細節 O ^ _ ^
①、首先導包
<!--監控 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!--Web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--服務注冊與發現 consul--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-consul-discovery</artifactId> </dependency> <!--服務調用 openFeign--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!--熔斷器 hystrix--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>
②、改 YML 配置文件
server: port: 80 #端口號 瀏覽網頁服務默認的端口號都是80,因此只需輸入網址即可,不用輸入“: 80”了 spring: application: name: cloud-hystrix-consumer-service #服務名 cloud: consul: host: localhost #consul的IP port: 8500 #consul啟動端口默認8500 discovery: service-name: ${spring.application.name} prefer-ip-address: true #不寫這個配置,在docker下的consul里面健康檢查會失敗 healthCheckInterval: 5s #健康檢查頻率 port: ${server.port} #注冊服務所在端口 feign: hystrix: enabled: true #在feign中開啟 Hystrix(熔斷器)
③、添加主啟動類
@SpringBootApplication @EnableFeignClients // 作用:啟用feign客服端 @EnableCircuitBreaker //SpringCloud中使用斷路器,需要加上此注解 public class HystrixConsumerMain80 { public static void main(String[] args) { SpringApplication.run(HystrixConsumerMain80.class, args); } }
④、業務邏輯 Service
/** * 朋友 @FeignClient 此注解還不會用? 別急 小編是老中醫 專治不會 哈哈 * 看小編上一講(地址:https://blog.csdn.net/Msxd_/article/details/105551238 * ==> OpenFeign簡介及@FeignClient等注解的使用) */ @FeignClient(value = "cloud-hystrix-provider-service", fallback = PaymentFallbackService.class) public interface PaymentFeignService { @GetMapping("/payment/hystrix/ok/{id}") RespResult<Payment> getPaymentById(@PathVariable("id") Integer id); //============================================================================================= 特殊說明:上面 @FeignClient 注解中 fallback = PaymentFallbackService.class 是干嘛的 ? 作用:比如客服端 調用服務端時,服務端突然 “掛了”,此時需要一個降級的方法 因為,你不可能讓客服端直接 來個 “ERROR” 吧 還不懂: 看上面 ==> 1.2、Hystris 能干嘛 ? PaymentFallbackService 如何寫 ??? 其實就是實現 這個 接口, 重寫里面的方法 ==> 往下看 5、降級 Service(Fallback) }
⑤、降級 Service(Fallback)
說明: 沒有,哈哈 ^ _ ^ 朋友 上面 哪一步 都說了 @Service public class PaymentFallbackService implements PaymentFeignService { @Override public RespResult<Payment> getPaymentById(Integer id) { return RespResult.error(500, " 服務端 getPaymentById 方法調用失敗 觸發熔斷降級 "); } }
⑥、業務邏輯 Controller
@Resource private PaymentFeignService paymentFeignService; //調用第四步中的接口 @GetMapping("/consumer/payment/get/{id}") public RespResult<Payment> getPaymentById(@PathVariable("id") Integer id){ log.info("我是使用的Feign"); //打印日志 return paymentFeignService.getPaymentById(id); // 調用里面的方法 } 總測試步驟: 1、啟動服務端 2、啟動消費端 3、地址欄輸入url: localhost/consumer/payment/get/1 // 為什么不加端口號(回去看 消費端 Yml 配置 有說明) 4、結果: 第一次:測試一切正常(客戶端和服務端 都正常啟動) 結果必然為正常結果 eg: { "code": 200, "message": "成功", "data": { "id": 1, "desc": "我還是從前那個少年" } } 第二次:測試不正常時(假如我們把服務端 停掉了) 結果必然為 Fallback 結果 eg: { "code": 500, "message": " 服務端 getPaymentById 方法調用失敗 觸發熔斷降級 ", "data": null } 此結果 就是我們在 第五步(降級 Service(Fallback)) 中配置 的 小編一頓 SAO 操作, 還可以吧 ^ _ ^
對 Hystris 實操 總結: 其實就兩點:
①、在 消費端 啟動類加:@EnableCircuitBreaker 注解
②、在@FeignClient 調用接口的屬性里加:fallback = PaymentFallbackService.class 並實現此方法,即可
咋青山不改,綠水長流,不妨看看小編其他作品,很香喲,哈哈,加油 ^ _ ^
三、總結
這是 SpringCloud 的 Hystris 篇,后續小編會從 “ GateWay(網關)、Config(分布式配置中心)…” 等堅持以博客的方式來分享自己對SpringCloud 的理解,並從不同角度和大家分享工作心得,並且含有相關Demo,最終小編會發布到GitHub上,供大家下載、分享、交流、指正,下面是源碼地址:
GitHub:https://github.com/msxdlb/Spring-Cloud-2020
有問題或錯誤請及時聯系小編或關注小編公眾號 “CodeCow”,小編一定及時回復和改正 啦
《 人生路上,你我都是過客,來去皆是緣分 》 隨緣——但須努力
2020/04/22 早 00:20