雪崩效應
- 在微服務系統中,一個請求會調用多個服務來完成,服務可用的情況下,當某一個服務出現網絡延遲或者故障時,請求就會被阻塞,等待故障服務響應。
- 在高併發的情況下,單個服務的延遲導致整個請求延遲或阻塞,可能在幾秒就使整個服務負載飽和
- 雪崩效應: 單個點服務的請求故障導致用戶請求阻塞,最終導致整個服務資源耗盡。由於服務依賴性,導致依賴該故障服務的其他服務也處於阻塞,最終導致其他服務資源耗盡,不可用。從而導致整個服務系統都不可用。
熔斷器
- 作用:防止雪崩效應
- 原理:服務調用過程中,發現請求延遲或者阻塞,等待一定時間,判定爲超時。並且根據設定的進行重試,重試次數都超時或者失敗。則進行熔斷,在一定時間內不在請求該服務,並預設返回默認值。保持請求邏輯,以及鏈路服務可用。
Hystrix
- Hystrix是NetFlix公司開源項目,提供熔斷器的功能,能夠阻止分佈式系統中出現聯動故障。
- Hystrix是通過隔離服務的訪問點組織聯動故障,並提供故障的解決方案,從而提高整個分佈式系統的彈性
工作機制
- 在一定的時間內,API接口的調用失敗次數小於設定的閥值時,熔斷器處於關閉狀態,該API接口正常提供服務
- 當API請求失敗超過閥值,Hystrix判定服務故障,打開熔斷器,處於打開狀態;請求該API接口會執行快速失敗的邏輯(fallback邏輯),請求的線程不會被阻塞
- 打開狀態的熔斷器,一段時間之後會處於半打開狀態,並將一定量的請求執行正常邏輯,另一部分執行fallback邏輯。若執行正常邏輯請求失敗,則熔斷器繼續打開,若成功,則熔斷器關閉。具有自我修復能力。
使用Feign Hystrix
- 因爲熔斷只是作用在服務調用這一端,因此只需要在Consumer 端做配置
jar包引入
- pom文件
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
- 由於Feign中已經依賴了Hystrix,不需要引入額外的Hystrix包
application.xml 配置文件
- feign.hystrix.enabled=true
spring.application.name=spring-cloud-hystrix-consumer
server.port=8080
eureka.client.serviceUrl.defaultZone=http://localhost:8000/eureka/
# 開啓熔斷
feign.hystrix.enabled=true
增加API熔斷
- 增加熔斷處理類(fallback),實現Feign客戶端接口,方法名同API名
/**
* Feign 結合Hystrix 熔斷器。如果熔斷回調該方法
*
* @author yanbin
* @since 2019/8/27 10:10
*/
@Component
public class IndexRemoteFallback implements IndexRemote {
@Override
public String hello(@RequestParam(value = "name") String name) {
return "Hystrix fallback! name: " + name;
}
}
- @FeignClient 註解增加:fallback屬性,指定定義好的類
@FeignClient(name = "spring-cloud-eureka-provider", fallback = IndexRemoteFallback.class)
public interface IndexRemote {
@RequestMapping(value = "/hello")
String hello(@RequestParam(value = "name") String name);
}
配置啓動類
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class HystrixConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(HystrixConsumerApplication.class, args);
}
}
請求入口
@RestController
@RequestMapping("/")
public class ConsumerController {
@Autowired
private IndexRemote indexRemote;
@RequestMapping("/hi/{name}")
public String hi(@PathVariable("name") String name) {
return indexRemote.hello(name);
}
}
調試
- 啓動Eureka Server Provider Consumer
正常請求
熔斷
- 停掉Provider 返回Fallback。Hystrix熔斷器起作用了
- 重啓Provider,恢復服務