SpringCloud系列-整合Hystrix的兩種方式


Hystrix [hɪst'rɪks],中文含義是豪豬,因其背上長滿棘刺,從而擁有了自我保護的能力。本文所說的Hystrix是Netflix開源的一款容錯框架,同樣具有自我保護能力。

本文目錄

一、Hystrix簡介二、Hystrix的設計原則三、Hystrix的工作原理四、Ribbon中使用熔斷器五、Feign中使用熔斷器六、踩到的坑

一、Hystrix簡介

Hystrix是由Netflix開源的一個延遲和容錯庫,用於隔離訪問遠程系統、服務或者第三方庫,防止級聯失敗,從而提升系統的可用性、容錯性與局部應用的彈性,是一個實現了超時機制和斷路器模式的工具類庫。

二、Hystrix的設計原則

  • 防止任何單獨的依賴耗盡資源(線程)
    過載立即切斷並快速失敗,防止排隊
  • 盡可能提供回退以保護用戶免受故障
  • 使用隔離技術(例如隔板,泳道和斷路器模式)來限制任何一個依賴的影響
  • 通過近實時的指標,監控和告警,確保故障被及時發現
  • 通過動態修改配置屬性,確保故障及時恢復
  • 防止整個依賴客戶端執行失敗,而不僅僅是網絡通信

三、Hystrix的工作原理

  • 使用命令模式將所有對外部服務(或依賴關系)的調用包裝在HystrixCommand或HystrixObservableCommand對象中,並將該對象放在單獨的線程中執行。
  • 每個依賴都維護着一個線程池(或信號量),線程池被耗盡則拒絕請求(而不是讓請求排隊)。
  • 記錄請求成功,失敗,超時和線程拒絕。
  • 服務錯誤百分比超過了閾值,熔斷器開關自動打開,一段時間內停止對該服務的所有請求。
  • 請求失敗,被拒絕,超時或熔斷時執行降級邏輯。
  • 近實時地監控指標和配置的修改。

當使用Hystrix封裝每個基礎依賴項時,每個依賴項彼此隔離,受到延遲時發生飽和的資源的限制,並包含回退邏輯,該邏輯決定了在依賴項中發生任何類型的故障時做出什么響應。

四、Ribbon中使用熔斷器

按照下面步驟改造之前的項目spring-cloud-consumer-ribbon

  1. pom.xml引入jar包
<!-- 整合hystrix -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
  1. 啟動類上添加@EnableHystrix注解

在啟動類上添加@EnableHystrix注解開啟Hystrix的熔斷器功能,改造后啟動類如下:

@EnableHystrix //在啟動類上添加@EnableHystrix注解開啟Hystrix的熔斷器功能。
@EnableEurekaClient
@SpringBootApplication
public class RibbonConsumerApplication {

    //當添加@LoadBalanced注解,就代表啟動Ribbon,進行負載均衡
    @LoadBalanced
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(RibbonConsumerApplication.class, args);
    }

}
  1. 添加HystrixConsumerController

在需要有熔斷機制的方法上添加 @HystrixCommand,屬性fallbackMethod是熔斷時返回的方法,編寫完成后HystrixConsumerController.java代碼如下:

/**
 * 消費者
 */

@Slf4j
@RestController
@RequestMapping("/hystrix/consumer")
public class HystrixConsumerController {

    @Autowired
    private RestTemplate restTemplate;

    /**
     * 調用 user微服務
     */

    @HystrixCommand(fallbackMethod = "getDefaultUser")
    @GetMapping("getUser")
    public String getUser(Integer id) {
        String url = "http://user-service/provider/getUser?id=" + id;
        return restTemplate.getForObject(url, String.class);
    }

    public String getDefaultUser(Integer id) {
        System.out.println("熔斷,默認回調函數");
        return "{\"id\":-1,\"name\":\"熔斷用戶\",\"password\":\"123456\"}";
    }
}
  1. 開始測試

代碼編寫之后,按順序啟動spring-cloud-eureka、spring-cloud-user-service和spring-cloud-consumer-ribbon,此時打開瀏覽器訪問http://localhost:8082/hystrix/consumer/getUser?id=2,服務正常,截圖如下:


服務正常截圖

然后停服務spring-cloud-user-service,再次訪問訪問http://localhost:8082/hystrix/consumer/getUser?id=2,此時會觸發熔斷,截圖如下:


觸發熔斷后截圖

五、Feign中使用熔斷器

Feign在整合到Spring Cloud時已經自帶了hystrix模塊,所以pom.xml中不需要額外引入feign依賴。

新建一個spring boot項目spring-cloud-consumer-fegin-hystrix,按照下面步驟操作。

  1. application.yml中開啟熔斷器
server:
  port: 8082 #服務端口
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:9001/eureka/
spring:
  application:
    name: fegin-hystrix-consumer

feign:
      hystrix:
        # feign熔斷器開關
        enabled: true
  1. 新建一個FeignClient接口

新建一個FeignClient接口UserFeginService並指定fallback,代碼如下:

//表示"user-service"的服務,指定fallback
@FeignClient(value = "user-service", fallback = UserFeginFailBackImpl.class)
public interface UserFeginService {

    @RequestMapping(value = "/provider/getUser")
    public String getUser(@RequestParam("id") Integer id);
}

@FeignClient注解參數說明:

  • name:指定FeignClient的名稱,如果項目使用了Ribbon,name屬性會作為微服務的名稱,用於服務發現。

  • fallback: 定義容錯的處理類,當調用遠程接口失敗或超時時,會調用對應接口的容錯邏輯,fallback指定的類必須實現@FeignClient標記的接口。

  • fallbackFactory: 工廠類,用於生成fallback類示例,通過這個屬性我們可以實現每個接口通用的容錯邏輯,減少重復的代碼

  • path: 定義當前FeignClient的統一前綴,類似於注解到類上的@RequestMapping的功能

  1. 添加熔斷處理類UserFeginFailBackImpl

代碼如下:

@Slf4j
@Component
public class UserFeginFailBackImpl implements UserFeginService {

    @Override
    public String getUser(Integer id) {
        log.info("熔斷,默認回調函數");
        return "{\"id\":-1,\"name\":\"熔斷用戶\",\"msg\":\"請求異常,返回熔斷用戶!\"}";
    }
}
  1. 添加Controller

添加FeginHystrixController,用於調用user-service,代碼如下:

@RestController
@RequestMapping("/hystrix/consumer")
public class FeginHystrixController {

    @Autowired
    private UserFeginService userFeginService;

    @GetMapping("/getUser")
    public String getUser(Integer id) {
        return userFeginService.getUser(id);
    }
}

5 開始測試

代碼編寫之后,按順序啟動spring-cloud-eureka、spring-cloud-user-service和spring-cloud-consumer-fegin-hystrix,此時打開瀏覽器訪問http://localhost:8082/hystrix/consumer/getUser?id=2,服務正常,截圖如下:


服務正常截圖

然后停服務spring-cloud-user-service,再次訪問訪問http://localhost:8082/hystrix/consumer/getUser?id=2,此時會觸發熔斷,截圖如下:


觸發熔斷后截圖

六、踩到的坑

  1. hystrix的異常fallback method wasn't found

出現這個異常是因為指定的備用方法和原方法的參數個數或類型不同造成的,所以需要統一參數的類型和個數。

到此SpringCloud兩種方式整合Hystrix的功能已經全部實現,有問題歡迎留言溝通哦!

完整源碼地址: https://github.com/suisui2019/springboot-study

推薦閱讀

1.SpringCloud系列-利用Feign實現聲明式服務調用)
2.手把手帶你利用Ribbon實現客戶端的負載均》
3.SpringCloud搭建注冊中心與服務注冊
4.Spring Boot配置過濾器的兩種方式!
5.編碼神器Lombok,學會后開發效率至少提高一倍!


限時領取免費Java相關資料,涵蓋了Java、Redis、MongoDB、MySQL、Zookeeper、Spring Cloud、Dubbo/Kafka、Hadoop、Hbase、Flink等高並發分布式、大數據、機器學習等技術。
關注下方公眾號即可免費領取:

Java碎碎念公眾號Java碎碎念公眾號

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM