Spring Cloud(六)Hystrix斷路器
阿新 • • 發佈:2018-12-16
一、雪崩效應
在微服務架構中,各個服務通過註冊與發現相互依賴。系統執行時可能會因為某個環節的服務出現故障導致服務間的呼叫超時或者失敗,進而導致整個系統的崩潰,這就是“雪崩效應”。
二、Hystrix介紹
2.1 原理
Hystrix是Netflix開源的一款容錯框架,包含常用的容錯方法:執行緒隔離、訊號量隔離、降級策略、熔斷技術。 Hystrix就像電路中的保險絲, 一旦後端服務不可用, 斷路器會直接切斷請求鏈, 避免傳送大量無效請求影響系統吞吐量, 並且斷路器有自我檢測並恢復的能力.
2.2 服務熔斷
斷路器最初是關閉狀態(Closed),當呼叫服務連續出錯或者超時時,保護器切換為熔斷狀態(Open),在後面的一段時間內所有的請求將被拒絕(Fail Fast),一段時間後,保護器將嘗試進入半熔斷狀態(Half Open),此時允許一定的請求進行嘗試。如果請求成功,則回到關閉狀態,吐過請求失敗則回到熔斷狀態。
- 熔斷機制的註解是@HystrixCommand。
- 熔斷機制是應對雪崩效應的一種鏈路保護機制,一般存在於服務端。
- 當扇出鏈路的某個服務出現故障或響應超時,會進行服務降級,進而熔斷該節點的服務呼叫,快速返回“錯誤”的相應資訊。
- Hystrix的熔斷存在閾值,預設是5秒內20次呼叫失敗就會觸發
2.2.1 熔斷案例
- 建立一個新的provider hystrix(可複製 provider 8001服務)。
- pom.xml加入hystrix依賴(一定要配合Eureka)
<dependency>
<groupId>org.springframework.cloud</ groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
- application.yml中配置埠等資訊。
server:
port: 8004
spring:
application:
name: spring-cloud-provider
eureka:
client:
service-url:
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002. com:7002/eureka,http://eureka7003.com:7003/eureka
instance:
instance-id: spring-cloud-provider-hystrix-8004 #更改服務客戶端顯示名
prefer-ip-address: true
info:
author: 陳玉林
app.name: spring-cloud-study
company.name: www.xxxx.com
- Controller類中,在需要配置Fallback的方法上加入@HystrixCommand(fallbackMethod = “XXX”)註解,XXX為FallBack方法名。該方法的引數列表和返回值型別必須與被呼叫的方法一樣
@HystrixCommand(fallbackMethod = "notService")
@RequestMapping("/hello/{name}")
public String index(@PathVariable String name) {
if (name.length()>6) {
throw new RuntimeException("服務出故障了!!");
}
return "Hello "+name+",welcome to study spring-cloud hystrix!!";
}
- 編寫對應的FallBack的方法。
public String notService(@PathVariable String name) {
return "Sorry, the waiter are unable to provide services to "+name+" at this time";
}
- 主啟動類中加入@EnableCircuitBreaker註解。
- 開啟服務,測試。
2.3 FallBack方法解耦與服務降級處理
2.3.1 降級
- 當系統整體資源快不夠的時候,忍痛將部分服務暫時關閉,待渡過難關後,再重新開啟關閉的服務。
- 降級處理是在客戶端完成的,與服務端沒有任何關係。
- 理解:所謂降級,一般是從整體負荷考慮,當某個服務熔斷之後,伺服器將不再被呼叫,此時客戶端可以自己準備一個本地的FallBack回撥,返回一個預設值。這樣做雖然服務水平下降,但是系統還可以正常執行,實現了高可用。
2.3.2 為什麼要解耦
如果按照上面的熔斷案例來做的話,Controller下的每個方法,都要給其編寫一個FallBack方法,如果方法過多,就會造成Controller程式碼混亂膨脹,耦合度高,加大了系統維護的難度,程式碼的耦合度也會高,這是十分不合理的,所以要將其解耦。
2.3.3 解耦和降級案例
- 建立一個consumer hystrix服務。
- 新增pom依賴(feign已經依賴hystrix,所有不需要新增hystrix依賴)。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<!--feign已經依賴hystrix-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
- 編寫配置檔案。
server:
port: 80
spring:
application:
name: spring-cloud-consumer-hystrix
eureka:
client:
service-url:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
register-with-eureka: false #作為消費者不提供服務,不應該註冊自己
#必須新增這一條
feign:
hystrix:
enabled: true
- 建立fallback類,記得新增掃描註解。
@Component
public class HelloRemoteHystrix implements HelloRemote{
@Override
public String hello(@RequestParam(value = "name") String name) {
return "Sorry, the waiter are unable to provide services to "+name+" at this time";
}
}
- 建立呼叫介面,新增指定fallback類,在服務熔斷的時候返回fallback類中的內容。
@FeignClient(name= "spring-cloud-provider", fallback = HelloRemoteHystrix.class)
public interface HelloRemote {
@RequestMapping(value = "/hello/{name}")
String hello(@RequestParam(value = "name") String name);
}
- 建立controller類。
@RestController
@RequestMapping("/consumer")
public class ConsumerController {
@Autowired
private HelloRemote helloRemote;
@RequestMapping("/hello/{name}")
public String index(@PathVariable("name") String name) {
return helloRemote.hello(name);
}
}
- 建立主啟動類。
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class SpringCloudConsumerHystrixApplication80 {
public static void main(String[] args) {
SpringApplication.run(SpringCloudConsumerHystrixApplication80.class, args);
}
}
- 啟動,測試,返回正常服務結果。
- 停掉服務提供者再次測試,返回fallback方法處理結果。 原始碼地址