以下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:123456@localhost:8083/eureka,http://user:123456@localhost: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熔斷器的學習,各位看官大佬爺有什么問題請留言區評論,大家一起討論解決。