上一章我們講了負載均衡
文章目錄
- 前言
- 一、Hystrix是什么?
- 二、Hystrix的作用是什么?Hystrix具體要保護什么?
- 2.1什么是微服務-雪崩效應
- 2.1服務熔斷原理
- 三、實踐
前言
一、Hystrix是什么?
有意思的是Hystrix在英文里面是豪豬的意思,手冊上這個圖笑死我了,這個分明是熊,哪會是豬,變種豬么?

仔細看圖,會發現這是滿身的刺,不管是熊是豬,給人感覺偽裝成了刺猬,一眼看過去很容易理解,滿身刺和偽裝目的是保護自己的作用,因此從圖中就可以看出它在微服務中是一款提供保護機制的組件,
二、Hystrix的作用是什么?Hystrix具體要保護什么?
Hystrix是Netflix開源的一個延遲和容錯庫,用于隔離訪問遠程服務和第三方庫級聯故障,也就是說Hystrix是一個庫,可以做什么?防止出現級聯失敗,
2.1什么是微服務-雪崩效應
微服務中,服務關系呼叫,錯綜復雜,一個請求可能需要呼叫多個服務介面才能實作,會形成非常復雜的呼叫鏈路,
假設 我們有兩個訪問量比較大的服務A和B,這兩個服務分別依賴C和D,C和D服務都依賴E服務
所有服務正常提供服務的情況下,請求順利被處理完,后面的請求一樣被處理,

A和B不斷的呼叫C,D處理客戶請求和回傳需要的資料,當E服務出現故障,Tomcat不會釋放執行緒,C和D的超時和重試機制又會被執行,后面又不斷有新的請求進來,形成阻塞,而服務器支持的執行緒和并發數又有限,請求一直阻塞,那么會導致服務器資源耗盡,導致服務E直接GG

由于新的呼叫不斷的產生,會導致C和D對E服務的呼叫大量的積壓,產生大量的呼叫等待和重試呼叫,慢慢會耗盡C和D的資源如記憶體或CPU,然后也down掉,

A和B服務會重復C和D的操作,資源耗盡,然后down掉,最終整個服務都不可訪問,

那么Hystrix如何解決這個雪崩的問題呢?主要是通過服務降級的方式,包括執行緒隔離,服務熔斷,
2.1服務熔斷原理
在服務熔斷中使用的熔斷器,也叫斷路器Circuit Breaker
熔斷器與家里使用的電路斷路器原理類似;當電路發生短路的時候能夠立刻熔斷,避免災難發生,在分布式系統中應用服務熔斷之后;服務呼叫方可以自己判斷哪些服務反應慢或者存在大量超時,可以針對這些服務進行主動熔斷,防止整個系統被拖垮,
Hystrix的服務熔斷機制,可以實作彈性容錯;當服務請求情況好轉之后;可以自動重連,通過短路的方式,將后續的請求直接拒絕,一段時間(一般是5秒)之后允許部分請求通過,如果呼叫成功則回到短路器關閉狀態,否則繼續打開,拒絕請求服務,

三個狀態:
Closed: 關閉狀態(斷路器關閉),所有請求都正常訪問,
Open: 打開狀態(斷路器打開),所有服務都會被降級,斷路器關閉時Hystrix會對請求情況計數,當一定時間內請求百分比達到閥值,則觸發熔斷,斷路器會完全打開,默認的失敗比例閥值是50%,請求次數最少不低于20次,
Half Open: 半開狀態,不是永久的,斷路器完全打開之后會進入休眠時間(默認是秒),隨后斷路器會自動進入半開狀態,此時通過釋放部分請求通過,若這些請求都是健康的,則關閉斷路器,否則保持打開,再次進入休眠計時,
三、實踐
老樣子,先拿到上一章的工程繼續修改 上一章工程
我們要用Hystrix,當然是需要引入包了,因此我們需要在custom-demo工程pom中引入,
<!-- hystrix -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
隨后要在custom-demo工程的handler層UserHandler添加一個例外時跳轉的方法,
@RestController
@RequestMapping("user")
@DefaultProperties(defaultFallback = "defaultFallback")
public class UserHandler {
@Autowired
private RestTemplate restTemplate;
@Autowired
private UserService userService;
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("/{id}")
@HystrixCommand
public String doGet(@PathVariable Long id){
// String url = "http://127.0.0.1:1001/user/"+id;
// return "<div><h1>custom-Service回應:</h1><div>"+restTemplate.getForObject(url, String.class);
// return userService.doGetUser(id);
// List<ServiceInstance> serviceInstances= discoveryClient.getInstances("user-service");
// String url = "http://"+serviceInstances.get(0).getHost()+":"+serviceInstances.get(0).getPort()+"/user/"+id;
/**
* 模擬id=1時目標服務器例外,
*/
if(1==id){
throw new RuntimeException("要訪問的服務器例外");
}
String url = "http://user-service/user/"+id;
return "<div><h1>custom-Service[通過注冊中心拉取服務]回應:</h1><div>"+restTemplate.getForObject(url, String.class);
}
/**
* 檢測到doGet例外時,會跳到這里來
* @return
*/
public String defaultFallback(){
return "默認提示:要訪問的服務器例外!";
}
}
啟動類加上@EnableCircuitBreaker注解,打開熔斷器,
@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
public class CustomService {
public static void main(String[] args) {
SpringApplication.run(CustomService.class, args);
}
@Bean
@LoadBalanced //負載均衡
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
隨后可以運行eureka、user-service、custom-demo三個工程,啟動好之后訪問
http://localhost:9001/user/1
二十次以上,這樣就會打開斷路器
此時再訪問
http://localhost:9001/user/2
就會看到

過一會兒再次訪問
http://localhost:9001/user/2
會發現此時斷路器已經自動關閉

以上的案例使用的是默認值,再yml可以不用配置,也可以如下配置,有興趣,您可以修改引數查看效果
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 1000 #觸發服務降級的時間,默認時1000ms
circuitBreaker:
errorThresholdPercentage: 50 #觸發熔斷比例閾值,默認值50%
sleepWindowInMillisecconds: 100000 #熔斷后休眠時長,默認5秒
requestVolumeThreshold: 20 #熔斷觸發最小請求次數,默認值20
本章例程
那么本章到這就先結束了,下一章介紹一下Feign,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/265633.html
標籤:AI
上一篇:Eolinker集成介紹
