1. 程式人生 > >【SpringCloud構建微服務系列】學習斷路器Hystrix

【SpringCloud構建微服務系列】學習斷路器Hystrix

ans sco hack function count 需要 color ping tle

一、Hystrix簡介

在微服務架構中經常包括多個服務層,比如A為B提供服務,B為C和D提供服務,如果A出故障了就會導致B也不可用,最終導致C和D也不可用,這就形成了雪崩效應
所以為了應對這種情況,我們就需要一種容錯機制,該機制需要實行以下兩點:

  1. 為網絡請求設置超時,以便盡快釋放資源
  2. 使用斷路器模式,就像家裏的電閘一樣,如果電流過大就會立刻跳閘以保護電路防止發生火災。當請求失敗率達到一定的閾值,斷路器就會打開,不會再請求依賴的服務。
    Hystrix就是這樣設計的,以實現容錯處理。

二、通用方式整合Hystrix

  1. 復制項目microservice-consumer-movie-ribbon
    改為microservice-consumer-movie-ribbon-hystrix
  2. 添加所需依賴
<dependency>
   		<groupId>org.springframework.cloud</groupId>
   		<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
  1. 在啟動類添加註解 @EnableHystrix 或者 @EnableCircuitBreaker以啟用
  2. 修改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-eurekamicroservice-provider-usermicroservice-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接口修改為如下

  1. /**
  2. * @author ship
  3. * @Description Feign的fallback測試
  4. * 使用@FeignClient的fallback屬性指定回退類
  5. * @Date: 2018-07-17 13:25
  6. */
  7. @FeignClient(name = "microservice-provider-user",fallback = FeignClientFallback.class)
  8. public interface UserFeignClient {
  9. @RequestMapping(value = "/{id}",method = RequestMethod.GET)
  10. User findById(@PathVariable("id") Long id);
  11. }
  12. /**
  13. * 回退類FeignClientFallback需實現Feign Client接口
  14. */
  15. @Component
  16. class FeignClientFallback implements UserFeignClient {
  17. @Override
  18. public User findById(Long id) {
  19. User user = new User();
  20. user.setId(-1L);
  21. user.setUsername("默認用戶");
  22. return user;
  23. }
  24. }

開始測試
1.按順序啟動服務microservice-discovery-eurekamicroservice-provider-usermicroservice-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接口

  1. /**
  2. * @author ship
  3. * @Description Feign的fallback測試
  4. * 使用@FeignClient的fallback屬性指定回退類
  5. * @Date: 2018-07-17 13:25
  6. */
  7. @FeignClient(name = "microservice-provider-user",fallbackFactory = FeignClientFallbackFactory.class)
  8. public interface UserFeignClient {
  9. @RequestMapping(value = "/{id}",method = RequestMethod.GET)
  10. User findById(@PathVariable("id") Long id);
  11. }
  12. /**
  13. * 通過FallbackFactory檢查回退原因
  14. */
  15. @Component
  16. class FeignClientFallbackFactory implements FallbackFactory<UserFeignClient>{
  17. private static final Logger logger = LoggerFactory.getLogger(FeignClientFallbackFactory.class);
  18. /**
  19. * 還可以根據不同的異常類型返回不同的結果
  20. * @param cause
  21. * @return
  22. */
  23. @Override
  24. public UserFeignClient create(Throwable cause) {
  25. return new UserFeignClient() {
  26. @Override
  27. public User findById(Long id) {
  28. //日誌最好放在各個fallback方法中,而不是create方法中
  29. //否則在引用啟動時,就會打印該日誌
  30. logger.info("fallback reason was:",cause);
  31. User user = new User();
  32. user.setId(-1L);
  33. user.setUsername("默認用戶");
  34. return user;
  35. }
  36. };
  37. }
  38. }

還可以根據不同的異常類型,返回不同的結果。
測試過程跟上面差不多,多了個查看日誌的過程,在此省略。
今天要睡覺了,明天繼續。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

四、Hystrix的監控

五、使用Hystrix Dashboard數據可視化

六、使用Turbine聚合監控數據

【SpringCloud構建微服務系列】學習斷路器Hystrix