1. 程式人生 > >Spring cloud微服務 Hystrix熔斷器學習教程

Spring cloud微服務 Hystrix熔斷器學習教程

       以下demo程式碼:https://github.com/wades2/HystrixtDemo

       官網定義:Hystrix是一個延遲容錯庫。在分散式環境中,許多服務依賴項中的一些不可避免地會失敗。Hystrix是一個庫,可通過新增延遲容錯和容錯邏輯來幫助您控制這些分散式服務之間的互動。Hystrix通過隔離服務之間的訪問點,阻止它們之間的級聯故障以及提供後備選項來實現這一點,所有這些都可以提高系統的整體彈性。

       因為在分散式系統中很多服務是相互依賴的,假如以下某個功能實現依賴於幾個服務:

       假如此時【家庭資訊查詢服務】由於請求過多或者伺服器原因出現了大批量服務不可用,【個人資訊查詢服務】由於無法請求到【家庭資訊查詢服務】,一直阻塞,造成伺服器壓力越來越大,後續又有【人員資訊查詢】的請求來了。就好比堵車的公路上又來了一大批車;此時會每個依賴關係都會在某些時候不可避免地失敗。如果主機應用程式未與這些外部故障隔離,則整個系統可能會崩潰。

        此時Hystrix熔斷器就發揮了作用:

        1、通過第三方客戶端庫訪問(通常通過網路)依賴關係,以防止和控制延遲和故障。
        2、在複雜的分散式系統中停止級聯故障。(在一段時間內偵測到許多類似的錯誤,會強迫其以後的多個呼叫快速失敗,不再訪問遠端伺服器)
        3、快速失敗並迅速恢復。(快速失敗後【個人資訊查詢服務】不會由於阻塞過載,就不會導致雪崩,)
        4、在可能的情況下,後退並優雅的降級。
        5、實現近實時監控,警報和操作控制。(如果熔斷器診斷【家庭資訊查詢服務】錯誤已經修正,應用程式會再次嘗試呼叫這個服務。)

        這樣我們就在之前學習Euraka+ribbon的基礎上加熔斷機制:

        首先在我們的EurekaCaller裡面新增上需要的依賴:

【注:如果不清楚的朋友或者沒有重頭看的朋友,這裡附上我demo的

git地址:https://github.com/wades2/EurekaDemo2

完整的搭建教程在:https://blog.csdn.net/asd529735325/article/details/85044158

如果你的Eureka和ribbon已經搭建好了可以直接跳過。】

我們的專案基本是這個樣子的:

Eurekacaller是這個樣子:

       新增pom依賴引入需要的jar包:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
        </dependency>

 重寫一下我們的Controller:

package com.example.demo.controller;

import com.example.demo.service.Services;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

@RestController
public class Controller {

    @Autowired
    private Services service;

    @RequestMapping(value = "getUser/routine",method = RequestMethod.GET)
    public String routine(@RequestParam String id){
        String json=service.routineService(id);
        return json;
    }
}

       然後是我們具體的service,負載的部分,我們的斷熔就放在service這裡,一旦請求超時或者失敗,立即失敗並觸發降級方法,我這裡的降級方法是:callback。

package com.example.demo.service;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.client.RestTemplate;

@Service
public class Services {
    @Autowired
    private RestTemplate restTemplate;

    //實現的callback方法來實現短路保護
    @HystrixCommand(fallbackMethod = "callback")
    public String routineService(String id){
        System.out.println(id);
        String jsons = restTemplate.getForObject("http://Eureka-client/user/getUser2", String.class);
        return jsons;
    }

    public String callback(String id){
        String msg="出現錯誤id:"+id;
        return msg;
    }

}

 因為在前期我們沒有掃描/user/getUser2所在的包路徑,所以這個是肯定掃描不到的,訪問一定是404not found的。

 然後啟動我們的5個啟動類,訪問http://localhost:8086/getUser/routine?id=52,我們可以看到訪問到了callback頁面:

這樣一來,即使EurkaClient都出現了問題或者過載,我們也可以降級處理。那我們再試試如果超時會怎麼樣。

修改配置檔案。,新增超時設定:

spring.application.name=Eureka_caller
server.port=8086
eureka.client.serviceUrl.defaultZone=http://user:[email protected]:8083/eureka,http://user:[email protected]:8082/eureka

#hystrix配置
hystrix.metrics.enabled=true
#預設的超時時間設定
hystrix.metrics.polling-interval-ms=2000

修改下Ribbon請求的路徑:

//實現的callback方法來實現短路保護
    @HystrixCommand(fallbackMethod = "callback")
    public String routineService(String id){
        System.out.println(id);
        String jsons = restTemplate.getForObject("http://Eureka-client/user/getUser", String.class);
        return jsons;
    }

 修改對應Service提供者的Client具體實現類(也就是修改EurekaClient和EurekaClient2),使其沉睡時間大於我們的熔斷請求延遲時間,模擬伺服器過載阻塞:

package com.example.demo.controller;

import com.netflix.appinfo.InstanceInfo;
import com.netflix.discovery.DiscoveryClient;
import com.netflix.discovery.EurekaClient;
import com.netflix.discovery.converters.Auto;
import com.netflix.discovery.shared.Applications;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;


@RestController
@RequestMapping("user")
public class UserController {

    @Autowired
    private EurekaClient eurekaClients;

    @GetMapping("getUser")
    public String getUser() {
        //todo 得到eureka server的服務例項
        InstanceInfo info=eurekaClients.getNextServerFromEureka("Eureka-client",false);
        try{
            Thread.sleep(60000);
        }catch (Exception e){
            e.printStackTrace();
        }
        return "hello one";
    }

}

我們看到請求後依然頁面被攔截熔斷了,因為等待時間60000毫秒遠遠大於了我們設定熔斷等待時間:2000毫秒。

 

以上就是我們關於Hystrix熔斷器的學習,各位看官大佬爺有什麼問題請留言區評論,大家一起討論解決。