javascript
Spring Cloud【Finchley】-08使用Hystrix实现容错
文章目錄
- 概述
- 實現(xiàn)容錯主要方式
- Hystrix簡介
- 通用方式整合Hystrix
- Step1 新建子module
- Step2 pom增加spring-cloud-starter-netflix-hystrix依賴
- Step3 啟動類增加@EnableCircuitBreaker或者@EnableHystrix注解
- Step4 控制層增加注解即容錯方法
- Step5 測試
- 代碼
概述
前面的幾篇博文,我們接觸到了Eureka實現(xiàn)服務(wù)的注冊于發(fā)現(xiàn)、Ribbon實現(xiàn)客戶端負(fù)載均衡、Feign實現(xiàn)聲明式的API調(diào)用,談到微服務(wù),容錯也是不得不提的話題之一。
Soring Cloud 集成了Hystrix來提供容錯的能力,從而實現(xiàn)微服務(wù)的容錯。
實現(xiàn)容錯主要方式
假設(shè)服務(wù)提供者的響應(yīng)很慢,那么消費(fèi)者的請求將會被強(qiáng)制等待,直到響應(yīng)或者超時。 在高負(fù)載的情況下,很有可能發(fā)生的情況是,當(dāng)依賴的服務(wù)不可用,自身的服務(wù)也被拖垮,這就是雪崩效應(yīng),當(dāng)服務(wù)提供者不可用導(dǎo)致消費(fèi)者不可用,并將不可用逐漸放大的過程。
容錯的主要手段:
為網(wǎng)絡(luò)請求設(shè)置超時: 通常情況下一次遠(yuǎn)程調(diào)用對應(yīng)一個線程,如果響應(yīng)太慢,這個線程就得不到釋放,而線程占用的資源當(dāng)然也不會被釋放,當(dāng)高并發(fā)或者未處理完的線程越來越多,資源終將被耗盡。
使用斷路器模式:如果有對某個微服務(wù)的請求存在大量超時,禁止訪問該微服務(wù),防止雪崩。 當(dāng)該微服務(wù)可用,斷路器可以自動診斷是否已經(jīng)恢復(fù),恢復(fù)訪問請求,從而實現(xiàn)微服務(wù)的自我修復(fù)
從而提升應(yīng)用的高可用性。
Hystrix簡介
https://github.com/netflix/hystrix
Hystrix是一個實現(xiàn)了超時機(jī)制和斷路器模式的工具類庫, 是由Netfix開源的一個延遲和容錯庫,用于隔離訪問遠(yuǎn)程系統(tǒng)、服務(wù)或者第三方庫,防止級聯(lián)失敗,從而提升系統(tǒng)可用性與容錯性。
機(jī)制:
當(dāng)Hystrix Command請求后端服務(wù)失敗數(shù)量超過一定比例(默認(rèn)50%), 斷路器會切換到開路狀態(tài)(Open).這時所有請求會直接失敗而不會發(fā)送到后端服務(wù).
斷路器保持在開路狀態(tài)一段時間后(默認(rèn)5秒), 自動切換到半開路狀態(tài)(HALF-OPEN). 這時會判斷下一次請求的返回情況, 如果請求成功, 斷路器切回閉路狀態(tài)(CLOSED), 否則重新切換到開路狀態(tài)(OPEN).
Hystrix的斷路器就像我們家庭電路中的保險絲, 一旦后端服務(wù)不可用, 斷路器會直接切斷請求鏈, 避免發(fā)送大量無效請求影響系統(tǒng)吞吐量,并且斷路器有自我檢測并恢復(fù)的能力.
Hystrix主要通過以下幾點實現(xiàn)延遲和容錯:
通用方式整合Hystrix
Spring Cloud官方指導(dǎo):https://cloud.spring.io/spring-cloud-static/Finchley.SR2/single/spring-cloud.html#_circuit_breaker_hystrix_clients
Step1 新建子module
因為熔斷是發(fā)生在調(diào)用方即消費(fèi)者,所以我們copy個消費(fèi)者的工程
父工程microservice-spring-cloud右鍵新建Maven Module 命名為:micorservice-consumer-movie-ribbon-hystrix ,為了簡單我們把micorservice-consumer-movie-ribbon的內(nèi)容copy到該子模塊,修改下application.yml中的spring.application.name即可。
Step2 pom增加spring-cloud-starter-netflix-hystrix依賴
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>Step3 啟動類增加@EnableCircuitBreaker或者@EnableHystrix注解
package com.artisan.micorservice;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.web.client.RestTemplate;@SpringBootApplication @EnableCircuitBreaker public class MicorserviceMovieRibbonHystrix {@Bean@LoadBalancedpublic RestTemplate restTemplate(){return new RestTemplate();}public static void main(String[] args) {SpringApplication.run(MicorserviceMovieRibbonHystrix.class, args);} }Step4 控制層增加注解即容錯方法
package com.artisan.micorservice.controller;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate;import com.artisan.micorservice.model.User; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;import lombok.extern.slf4j.Slf4j;@RestController public class MovieController {@Autowiredprivate RestTemplate restTemplate;@AutowiredLoadBalancerClient loadBalancerClient;@HystrixCommand(fallbackMethod = "findByIdDefault")@GetMapping("/movie/{id}")public User findById(@PathVariable Long id) {return this.restTemplate.getForObject("http://microservice-provider-user/user/" + id, User.class);}/*** * @param id* @return* @desc 當(dāng)請求失敗、超時、被拒絕,或當(dāng)斷路器打開時,執(zhí)行的邏輯*/public User findByIdDefault(Long id) {User user = new User();user.setId(id);user.setUsername("默認(rèn)用戶");return user;}}從上述Controller層的方法中,可以看到我們在findById方法上增加了注解 @HystrixCommand(fallbackMethod = “findByIdDefault”),并通過fallbackMethod 屬性指定了當(dāng)請求失敗、超時、被拒絕,或當(dāng)斷路器打開時,執(zhí)行的方法findByIdDefault.
HystrixCommand注解還可以使用注解HystrixProperty的commandProperties屬性來配置HystrixCommand
比如
@HystrixCommand(fallbackMethod = "findByIdDefault",commandProperties= {@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="5000"),@HystrixProperty(name="metrics.rollingStats.timeInMilliseconds",value="10000")},threadPoolProperties= {@HystrixProperty(name="coreSize",value="1"),@HystrixProperty(name="maxQueueSize",value="10")})@GetMapping("/movie/{id}")public User findById(@PathVariable Long id) {return this.restTemplate.getForObject("http://microservice-provider-user/user/" + id, User.class);}可配置的屬性見官網(wǎng): https://github.com/Netflix/Hystrix/tree/master/hystrix-contrib/hystrix-javanica#configuration
Step5 測試
訪問http://localhost:8761/ 確認(rèn)下服務(wù)已經(jīng)注冊成功。
訪問: http://localhost:7902/movie/2 ,返回
{"id":2,"username":"artisan2","name":"小工匠二","age":20,"balance":200.00}停止 micorservice-provider-user,服務(wù)提供者 ,注冊中心上已經(jīng)沒有該服務(wù)了。
訪問http://localhost:7902/movie/2 ,可訪問多次,均返回
{"id":2,"username":"默認(rèn)用戶","name":null,"age":null,"balance":null}已經(jīng)走到了我們自定義的方法中。
再次啟動 micorservice-provider-user,服務(wù)提供者
訪問http://localhost:7902/movie/2
{"id":2,"username":"artisan2","name":"小工匠二","age":20,"balance":200.00}服務(wù)已經(jīng)恢復(fù)。
當(dāng)請求失敗、被拒絕、超時或者斷路器打開時都會進(jìn)入到回退的方法,當(dāng)進(jìn)入回退方法并不意味著斷路器已經(jīng)被打開。
代碼
https://github.com/yangshangwei/SpringCloudMaster/tree/master/micorservice-consumer-movie-ribbon-hystrix
總結(jié)
以上是生活随笔為你收集整理的Spring Cloud【Finchley】-08使用Hystrix实现容错的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring Cloud【Finchle
- 下一篇: Spring Cloud【Finchle