1.雪崩效應
雪崩效應
如上圖所示,假設我們有3個微服務A,B,C,A調用B,B調用C,如果C掛掉了,由于B是同步調用,不斷等待,導致資源耗盡,B也掛掉,接下來A也掛掉了,造成了雪崩效應!為了防止雪崩效應,所以我們要在本篇文章中介紹Hystrix。
2.Hystrix
Hystrix
hystrix對應的中文名字是“豪豬”,豪豬周身長滿了刺,能保護自己不受天敵的傷害,代表了一種防御機制,反正這種豬我是沒吃過的,不敢吃。那么Hystrix又具備什么樣的特點呢:
2.1服務降級
雙11的時候我們經??吹桨驯粩D爆了,這其實就是一種服務降級。那么Hystrix是怎么做到服務降級的呢?
2.1.1優先核心服務,非核心服務不可用或者弱可用
比如在一個系統中我們可能有限保證訂單和支付服務,但是對于廣告之類的服務就若花掉
2.1.2通過HystrixCommand注解
2.1.3fallbackMethod中具體實現降級邏輯
2.1.4具體使用
2.1.4.1pom.xml
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>
2.1.4.2啟動類
//@SpringBootApplication //@EnableDiscoveryClient //@EnableCircuitBreaker @SpringCloudApplication public class OrderApplication { public static void main(String[] args) { SpringApplication.run(OrderApplication.class, args); } }
在這里我們引入了@EnableCircuitBreaker這個注解,但是可以看到我們的main函數所在的類上面有好多注解了,我們這里用一個SpringCloudApplication注解包含上面的3個注解
2.1.4.3HystrixCommand與fallback的使用
@HystrixCommand(fallbackMethod="fallback") @GetMapping("/getProductInfoList") public String getProductInfoList(@RequestParam("number") Integer number) { RestTemplate restTemplate = new RestTemplate(); return restTemplate.postForObject("http://127.0.0.1:8005/product/listForOrder", Arrays.asList("157875196366160022"), String.class); } private String fallback() { return "太擁擠了, 請稍后再試~~"; }
假設你的方法有幾萬個,上面的這種寫法用@HystrixCommand這個注解肯定要用幾萬次,太麻煩了,我們來優化和更新一下:
@RestController @DefaultProperties(defaultFallback = "defaultFallback") public class HystrixController { @HystrixCommand(commandProperties = { @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000") }) @GetMapping("/getProductInfoList") public String getProductInfoList(@RequestParam("number") Integer number) { RestTemplate restTemplate = new RestTemplate(); return restTemplate.postForObject("http://127.0.0.1:8005/product/listForOrder", Arrays.asList("157875196366160022"), String.class); } private String defaultFallback() { return "默認提示:太擁擠了, 請稍后再試~~"; } }
直接在Controller上面寫了一個DefaultProperties這樣的注解,然后定義了一個defaultFallback這樣的方法,我們在getProductInfoList這個方法上的@HystrixCommand注解上可以不在注明fallback方法了,因為我們都用defaultFallback了。但是在這里我們用了一個commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000"),這個表示當調用方法超過3秒鐘時,就服務降級
2.2依賴隔離
Hystrix使用依賴隔離完成的是線程池的隔離,它為每個HystrixCommand創建一個單獨的線程池。這樣某個在HystrixCommand包裝下的依賴服務出現延遲過高的情況,也只是對該依賴的服務調用產生影響,并不會拖慢其他服務。使用了HystrixCommand將某個函數包裝成Hystrix命令時,Hystrix框架就會自動的為這個函數實現了依賴隔離,所以依賴隔離和服務降級是一體化實現的。
2.3服務熔斷
當服務調用發生錯誤到一定比例的時候,斷路器就會打開,服務的調用會轉向另外一個指定的調用方法,這就是服務熔斷,這樣說比較抽象,我們看看下面這個圖:
斷路器
斷路器一共有三個狀態,初始的時候是closed狀態,如果用戶不斷調用且失敗次數達到了一定的閾值,這個時候斷路器就會變成open狀態,接下來用戶不斷調用這個接口都是進入到另一個缺省方法中。但是斷路器不會一直處于open狀態,當open狀態達到一定時間后,斷路器會變成half open狀態,進入half open狀態后,將會允許請求再次訪問真正的服務,如果訪問成功了,斷路器會變成closed狀態,服務恢復正常,如果還失敗又再次進入到open狀態。
2.3.1代碼演示
@HystrixCommand(commandProperties = { @HystrixProperty(name = "circuitBreaker.enabled", value = "true"), //設置熔斷 @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"), //請求數達到后才計算 @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"), //休眠時間窗 @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60"), //錯誤率 }) @GetMapping("/getProductInfoList") public String getProductInfoList(@RequestParam("number") Integer number) { if (number % 2 == 0) { return "success"; } RestTemplate restTemplate = new RestTemplate(); return restTemplate.postForObject("http://127.0.0.1:8005/product/listForOrder", Arrays.asList("157875196366160022"), String.class); }
通過代碼,我們可以看到,有四個參數,但是最重要的還是這三個參數:
1.circuitBreaker.requestVolumeThreshold 請求數達到后才計算
2.circuitBreaker.sleepWindowInMilliseconds open狀態達到這個時間后,就會進入到半熔斷狀態
3.circuitBreaker.errorThresholdPercentage 失敗請求比例
2.3.2使用配置項
從上面的代碼中,我們可以看到,很多配置項都是寫在了代碼里面,接下來,我們把這些配置放到配置文件里面去:
@HystrixCommand @GetMapping("/getProductInfoList") public String getProductInfoList(@RequestParam("number") Integer number) { if (number % 2 == 0) { return "success"; } RestTemplate restTemplate = new RestTemplate(); return restTemplate.postForObject("http://127.0.0.1:8005/product/listForOrder", Arrays.asList("157875196366160022"), String.class); }
在yaml文件中添加這樣的配置:
hystrix: command: default: execution: isolation: thread: timeoutInMilliseconds: 1000 getProductInfoList: execution: isolation: thread: timeoutInMilliseconds: 3000
在yaml文件中有一個getProductInfoList配置項,和方法名一模一樣,還有一個default選項,default選項表示所有被HystrixCommand注解的方法都可以用這個配置,getProductInfoList表示只有這個方法可以用這個配置項。
2.3.3feign-hystrix的使用
上面的小章節我們使用的是RestTemplate模板,接下來我們使用feign配合hystrix來進行使用,有意思的是大家可以看看spring-cloud-starter-feign的pom.xml其實已經在內部依賴了hystrix。
2.3.3.1yaml配置文件
feign: hystrix: enabled: true
2.3.3.2FeignClient
@FeignClient(name = "product", fallback = ProductClient.ProductClientFallback.class) public interface ProductClient { @PostMapping("/product/listForOrder") List<ProductInfoOutput> listForOrder(@RequestBody List<String> productIdList); @PostMapping("/product/decreaseStock") void decreaseStock(@RequestBody List<DecreaseStockInput> decreaseStockInputList); @Component static class ProductClientFallback implements ProductClient { @Override public List<ProductInfoOutput> listForOrder(List<String> productIdList) { return null; } @Override public void decreaseStock(List<DecreaseStockInput> decreaseStockInputList) { } } }
兩個注意點,一個是fallback的配置,還有一個是內部類需要加上@Component注解
2.3.3.3調用方記得加上ComponentScan
2.4監控HystrixDashBoard
2.4.1pom.xml
spring-cloud-starter-hystrix-dashboard
2.4.2yaml文件
management: context-path: /
2.4.3訪問
IP:PORT/hystrix
服務容錯就講到這里,下一章節我們講解下服務跟蹤。希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。