【SpringCloud構建微服務系列】學習斷路器Hystrix
一、Hystrix簡介
在微服務架構中經常包括多個服務層,比如A為B提供服務,B為C和D提供服務,如果A出故障了就會導致B也不可用,最終導致C和D也不可用,這就形成了雪崩效應。
所以為了應對這種情況,我們就需要一種容錯機制,該機制需要實行以下兩點:
- 為網絡請求設置超時,以便盡快釋放資源
- 使用斷路器模式,就像家裏的電閘一樣,如果電流過大就會立刻跳閘以保護電路防止發生火災。當請求失敗率達到一定的閾值,斷路器就會打開,不會再請求依賴的服務。
Hystrix就是這樣設計的,以實現容錯處理。
二、通用方式整合Hystrix
- 復制項目microservice-consumer-movie-ribbon
- 添加所需依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
- 在啟動類添加註解 @EnableHystrix 或者 @EnableCircuitBreaker以啟用
- 修改MovieController代碼,讓findById方法具備容錯能力
@RestController
public class MovieController {
@Autowired
private LoadBalancerClient loadBalancerClient;
@Autowired
private RestTemplate restTemplate;
private static final Logger logger = LoggerFactory.getLogger(MovieController.class);
@HystrixCommand(fallbackMethod = "findByIdFallBack" )
@GetMapping("/user/{id}")
public User findById(@PathVariable Long id){
//microservice-provider-user是虛擬主機名,默認和服務名稱一致
//不能包括"_"之類的字符,否則Ribbon在調用時會報異常
return this.restTemplate.getForObject("http://microservice-provider-user/"+id,User.class);
}
public User findByIdFallBack(Long id){
User user = new User();
user.setId(-1L);
user.setAge(0);
user.setBalance(BigDecimal.ZERO);
user.setName("默認用戶");
user.setUsername("默認用戶");
return user;
}
}
這裏考慮篇幅就不細說 @HystrixCommand註解的屬性配置問題了。
測試
1.分別啟動服務microservice-discovery-eureka,microservice-provider-user,microservice-consumer-movie-ribbon-hystrix
2.遊覽器訪問http://localhost:8010/user/1獲得如下結果
{"id":1,"username":"xxx","name":"zhangsan","age":22,"balance":100}
3.關掉服務microservice-provider-user再重新請求,獲得如下結果。
{"id":-1,"username":"默認用戶","name":"默認用戶","age":0,"balance":0}
說明服務不可用時,進入到了回退方法。
為服務引入SpringBoot Actuator,再訪問/health端點可以查看斷路器狀態,不過我嘗試失敗了。
三、Feign使用Hystrix
3.1為Feign添加回退
1.復制項目microservice-consumer-movie-feign改為microservice-consumer-movie-feign-hystrix-fallback,註意pom文件spring-cloud-starter-eureka 和 spring-cloud-starter-feign 已經過時。
2.Feign默認已經整合了Hystrix,所以不需要額外引入依賴。
3.將之前的UserFeignClient接口修改為如下
- /**
- * @author ship
- * @Description Feign的fallback測試
- * 使用@FeignClient的fallback屬性指定回退類
- * @Date: 2018-07-17 13:25
- */
- "microservice-provider-user",fallback = FeignClientFallback.class) (name =
- public interface UserFeignClient {
- "/{id}",method = RequestMethod.GET) (value =
- User findById(@PathVariable("id") Long id);
- }
- /**
- * 回退類FeignClientFallback需實現Feign Client接口
- */
- class FeignClientFallback implements UserFeignClient {
- public User findById(Long id) {
- User user = new User();
- user.setId(-1L);
- user.setUsername("默認用戶");
- return user;
- }
- }
開始測試
1.按順序啟動服務microservice-discovery-eureka,microservice-provider-user,microservice-consumer-movie-feign-hystrix-fallback
2.訪問http://localhost:8010/user/1可獲得正常結果
3.停止microservice-provider-user後再次訪問獲得如下結果說明已經成功了。
{"id":-1,"username":"默認用戶","name":"默認用戶","age":0,"balance":0}
如果你遇到了404問題,可能是因為從Spring Cloud Dalston開始,Feign默認是不開啟Hystrix的。所以需要在application.yml文件上添加如下內容。
註意單詞不要拼寫錯,我就是因為enabled寫成了enable折騰了半天。。。。
3.2通過fallback factory檢查回退原因
1.復制項目microservice-consumer-movie-feign改為microservice-consumer-movie-feign-hystrix-fallback-factory
2.修改UserFeignClient接口
- /**
- * @author ship
- * @Description Feign的fallback測試
- * 使用@FeignClient的fallback屬性指定回退類
- * @Date: 2018-07-17 13:25
- */
- "microservice-provider-user",fallbackFactory = FeignClientFallbackFactory.class) (name =
- public interface UserFeignClient {
- "/{id}",method = RequestMethod.GET) (value =
- User findById(@PathVariable("id") Long id);
- }
- /**
- * 通過FallbackFactory檢查回退原因
- */
- class FeignClientFallbackFactory implements FallbackFactory<UserFeignClient>{
- private static final Logger logger = LoggerFactory.getLogger(FeignClientFallbackFactory.class);
- /**
- * 還可以根據不同的異常類型返回不同的結果
- * @param cause
- * @return
- */
- public UserFeignClient create(Throwable cause) {
- return new UserFeignClient() {
- public User findById(Long id) {
- //日誌最好放在各個fallback方法中,而不是create方法中
- //否則在引用啟動時,就會打印該日誌
- logger.info("fallback reason was:",cause);
- User user = new User();
- user.setId(-1L);
- user.setUsername("默認用戶");
- return user;
- }
- };
- }
- }
還可以根據不同的異常類型,返回不同的結果。
測試過程跟上面差不多,多了個查看日誌的過程,在此省略。
今天要睡覺了,明天繼續。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
四、Hystrix的監控
五、使用Hystrix Dashboard數據可視化
六、使用Turbine聚合監控數據
【SpringCloud構建微服務系列】學習斷路器Hystrix