【分佈式】SpringCloud(6)--Hystrix服務熔斷與降級

1.Hystrix概述

1.1.什麼是Hystrix

Hystrix是一個用於處理分佈式系統的延遲和容錯的開源庫。Hystrix主要用於處理分佈式系統中複雜多變的服務依賴調用失敗、超時、異常等狀況,保證一個服務依賴出問題的狀況下,提供一個服務預期的、可處理的備選響應(FallBack),避免微服務總體級聯故障,以提升分佈式系統的彈性。git

 

1.2.Hystrix的做用是什麼

Hystrix旨在執行如下操做:github

  • 提供保護並控制延遲和失敗,以及經過第三方客戶端庫(一般是經過網絡)訪問依賴項致使的失敗。
  • 切斷複雜的分佈式系統中的級聯故障。
  • 快速響應並快速恢復。
  • 回退並在可能的狀況下正常降級。
  • 啓用近乎實時的監視,警報和操控。

 

1.3.Hystrix能解決什麼問題

Hystrix在分佈式項目中主要用於處理:spring

  • 服務降級
  • 服務熔斷
  • 服務限流
  • 接近實時地監控

 

2.Hystrix服務熔斷

2.1.服務熔斷機制

首先對應服務熔斷咱們要理解「服務雪崩」的概念,服務雪崩是多個微服務之間調用的時候,假設微服務A調用微服務B和微服務C,微服務B和微服務C又調用其它的微服務,這就是所謂的「扇出」。若是扇出的鏈路上某個微服務的調用響應時間過長或者不可用,對微服務A的調用就會佔用愈來愈多的系統資源,進而引發系統崩潰,就是所謂的「雪崩」。數據庫

熔斷機制是應對雪崩效應的一種微服務鏈路保護機制api

當扇出鏈路的某個微服務不可用或者響應時間太長時,就會經過熔斷該節點微服務的調用,快速返回錯誤的響應信息。當檢測到該節點微服務調用響應正常後恢復調用鏈路。網絡

 

2.2.簡單實現一個Hystrix熔斷

在SpringCloud框架裏熔斷機制經過Hystrix實現。Hystrix會監控微服務間調用的情況,當失敗的調用到必定閾值,缺省是5秒內20次調用失敗就會啓動熔斷機制。熔斷機制的註解是@HystrixCommand。mybatis

這裏咱們仍是基於咱們以前博客的微服務項目springcloud-provider-dept-8001 服務端 複製一份做爲hystrix的微服務項目。app

①添加hystrix pom.xml依賴包:框架

<!--引入hystrix-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-hystrix</artifactId>
    <version>1.4.6.RELEASE</version>
</dependency>

 

②修改application.yml配置,修改了實例名稱:分佈式

server:
  port: 8001
##省略了數據庫鏈接信息與mybatis配置

#eureka的配置,肯定客戶端服務註冊到eureka服務列表內
eureka:
  client:
    service-url:
      #集羣配置
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
      #defaultZone: http://localhost:7001/eureka/
  instance:
    instance-id: springcloud-provider-dept-hystrix-8001  #修改eureka上默認的服務描述信息
    prefer-ip-address: true  #訪問路徑能夠顯示ip地址

 

③基於Controller層的調用方法經過id獲取Dept用戶來作異常斷定:

@RestController
@RequestMapping("/dept")
public class DeptController {
    @Autowired
    private DeptService service;

    @GetMapping("/queryById/{id}")
    /*@HystrixCommand表示一旦調用服務方法失敗並拋出了異常信息以後,
    會自動調用@HystrixCommand標註好的fallbackMethod中指定名稱的方法*/
    @HystrixCommand(fallbackMethod = "processHystrixGet")
    public Dept queryById(@PathVariable("id") Long id){
        Dept dept = service.queryById(id);  //模擬當查詢不到id或者id信息異常時返回錯誤異常的提示
        if(null == dept){
            throw new RuntimeException("id=>" + id + "不存在該用戶,或者用戶信息沒法找到!");
        }
        return dept;
    };

    //熔斷備選方法:異常回調信息顯示
    public Dept processHystrixGet(@PathVariable("id") Long id){
        return new Dept()
                .setDeptno(id)
                .setDname("id=>" + id + "沒有對應的信息,null--@Hystrix")
                .setDbSource("no this database in MySQL");
    }
}

 

④在主啓動類上添加對hystrix的熔斷機制的支持:

@SpringBootApplication
@EnableEurekaClient  //在服務啓動後自動註冊到eureka中
@EnableDiscoveryClient  //服務發現
@EnableCircuitBreaker  //啓用對hystrix的熔斷機制的支持
public class DeptProvider8001_Hystrix_App {
    public static void main(String[] args) {
        SpringApplication.run(DeptProvider8001_Hystrix_App.class, args);
    }
}

 

⑤啓動Eureka客戶端、Hystrix服務端進行訪問驗證:

訪問正常存在的服務id,能返回正常數據:

 

訪問異常不存在的id時,返回fallback方法中的信息:

 

 能夠看出,當執行調用某個微服務發生異常時,Hystrix能經過自定義的fallbackMethod作異常的錯誤返回,快速進行異常熔斷機制。

服務熔斷是在服務運行的狀況下,對於服務內部執行錯誤的異常狀況的一種處理方式。

 

3.Hystrix服務降級

3.1.服務降級機制

服務降級是從網站總體的負載考慮,當某個服務在某一時間內承受大量的服務請求,而須要極大的資源消耗,須要關閉當前系統的某些服務,作資源的擴充。犧牲單個服務的運行,當再次訪問這單個服務的時候,經過服務降級處理,返回給客戶設定的默認缺省值

至關於棄軍保帥,維護的是整個系統的可用性。

 

3.2.簡單實現服務降級

服務降級這裏從客戶端進行實現。

(1)首先在springcloud-api中定義一個降級以後的回調函數類,實現FalllbackFactory接口,接口中實現了對應請求信息的異常處理方法:

@Component  //注意不要忘記添加,須要把類加載進Spring容器中才能獲取到
public class DeptClientServiceFallbackFactory implements FallbackFactory<DeptClientService> {
    @Override
    public DeptClientService create(Throwable throwable) {
        return new DeptClientService() {
            @Override
            public boolean addDept(Dept dept) {
                return false;
            }

            @Override
            public Dept queryById(Long id) {
                return new Dept().setDeptno(id).setDname("該ID:" + id + "沒有對應的信息,Consumer客戶端提供的降級信息,此刻服務provider已經關閉").
                        setDbSource("no this database in MySQL");
            }

            @Override
            public List<Dept> queryAll() {
                return null;
            }
        };
    }
}

 

(2)對應api接口中使用fallabckFatory去指定調用的是哪一個class實現類:

//value中對應服務提供方的名字
//服務降級:表示DeptClientService當前接口中任何一個方法出了問題:都去找DeptClientServiceFallbackFactory回調處理
@FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT", fallbackFactory = DeptClientServiceFallbackFactory.class)
@Component //注入到容器中
public interface DeptClientService {
    /**
     * 接口中的三個方法對應服務提供者的三個方法
     * 這裏面的接口對應服務提供者的controller接口,名稱必須一致,而後接口的Mapping映射url必須一致
     * @param dept
     * @return
     */

    @PostMapping("/dept/add")
    public boolean addDept(Dept dept);

    @GetMapping("/dept/queryById/{id}")
    public Dept queryById(@PathVariable("id") Long id);

    @GetMapping("/dept/queryAll")
    public List<Dept> queryAll();
}

 

(3)基於FeignClinet調用,則須要修改服務提供者中application.yml,開啓feign中對hystrix的支持:

#開啓降級feign.hystrix支持
feign:
  hystrix:
    enabled: true

 

(4)測試驗證:

步驟:啓動三個Eureka註冊中心700一、700二、7003,啓動provider-dept-8001做爲服務提供者、啓動consumer-dept-feign服務消費者:

能夠看到服務提供者已經註冊進去並正常運行:

 

 

經過客戶端consumer-feign的81端口也能訪問到對應的id數據:

 

(5)模擬服務熔斷異常:

關閉服務提供方provider-dept-8001,同時訪問81端口的數據請求:

 

 能夠看到此時調用到了咱們編寫的fallbackFactory中的回調方法顯示降級信息。

因此即便服務關閉以後,Hystrix的服務熔斷機制也能避免大量重複無效訪問帶來的服務異常,能較好的提供客戶體驗。

 

本節涉及實例及相關代碼已上傳至github:

https://github.com/devyf/SpringCloud_Study/tree/main/springcloud_hello

相關文章
相關標籤/搜索