Netflix Hystrix是SOA/微服務架構中提供服務隔離、熔斷、降級機制的工具/框架。Netflix Hystrix是斷路器的一種實現,用於高微服務架構的可用性,是防止服務出現雪崩的利器。java
在分佈式架構中,一個應用依賴多個服務是很是常見的,若是其中一個依賴因爲延遲太高發生阻塞,調用該依賴服務的線程就會阻塞,若是相關業務的QPS較高,就可能產生大量阻塞,從而致使該應用/服務因爲服務器資源被耗盡而拖垮。web
另外,故障也會在應用之間傳遞,若是故障服務的上游依賴較多,可能會引發服務的雪崩效應。就跟數據癱瘓,會引發依賴該數據庫的應用癱瘓是同樣的道理。spring
當一個應用依賴多個外部服務,一切都正常的狀況下,以下圖:數據庫
若是其中一個依賴發生延遲,當前請求就會被阻塞json
出現這種狀況後,若是沒有應對措施,後續的請求也會被持續阻塞緩存
每一個請求都佔用了系統的CPU、內存、網絡等資源,若是該應用的QPS較高,那麼該應用因此的服務資源會被快速消耗完畢,直至應用死掉。若是這個出問題的依賴(Dependency I),不止這一個應用,亦或是受影響的應用上層也有更多的依賴,那就會帶來咱們前面所提到的服務雪崩效應。 因此,爲了應對以上問題,就須要有支持服務隔離、熔斷等操做的工具。服務器
在經過網絡依賴服務出現高延遲或者失敗時,爲系統提供保護和控制 能夠進行快速失敗,縮短延遲等待時間和快速恢復:當異常的依賴回覆正常後,失敗的請求所佔用的線程會被快速清理,不須要額外等待 提供失敗回退(Fallback)和相對優雅的服務降級機制 提供有效的服務容錯監控、報警和運維控制手段網絡
Hystrix將請求的邏輯進行封裝,相關邏輯會在獨立的線程中執行架構
Hystrix有自動超時策略,若是外部請求超過閾值,Hystrix會以超時來處理併發
Hystrix會爲每一個依賴維護一個線程池,當線程滿載,不會進行線程排隊,會直接終止操做
Hystrix有熔斷機制: 在依賴服務失效比例超過閾值時,手動或者自動地切斷服務一段時間 因此,當引入了Hystrix以後,當出現某個依賴高延遲的時候
可能會有人有疑問,爲何不依賴於HTTP Client去作容錯保護(快速失敗、熔斷等),而是在訪問依賴以外經過線程&線程池隔離的方式作這個斷路器(Hystrix)`
主要是如下幾個方面:
修改pom.xml,引入Spring Cloud Netflix Hystrix
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
修改啓動類Application.java,增長@EnableHystrix註解開啓Hystrix
@EnableHystrix
@EnableDiscoveryClient
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
修改TestService.java,增長斷路器功能
@Service
public class TestService {
@Autowired
private RestTemplate restTemplate;
@HystrixCommand(fallbackMethod = "indexError")
public Object index() {
return restTemplate.getForObject("http://testservice", String.class);
}
public Object plus(int numA, int numB) {
String url = String.format("http://testservice/plus?numA=%s&numB=%s", numA, numB);
return restTemplate.getForObject(url, String.class);
}
public Object indexError() {
return "{\"code\": 999,\"message\": \"服務斷路\"}";
}
}
啓動 Application 項目, 訪問:http://localhost:8604/ti ,將看到
{
"code": 0,
"message": "hello",
"content": null,
"serviceName": "testservice",
"host": "localhost:8602"
}
關閉testservice,而後再訪問 http://localhost:8604/ti ,將看到
{
"code": 999,
"message": "服務斷路"
}
至此完成Ribbon+Hystrix的熔斷。
feign:
hystrix:
enabled: true
新建 TestServiceHystrix.java做爲TestService的斷路處理實現
@Component
public class TestServiceHystrix implements TestService {
@Override
public String indexService() {
return "{\"code\": 999,\"message\": \"服務斷路\"}";
}
@Override
public Result plusService(int numA, int numB) {
Result result = new Result();
result.setCode(999);
result.setMessage("服務斷路");
return new Result();
}
@Override
public Result plusabService(Plus plus) {
Result result = new Result();
result.setCode(999);
result.setMessage("服務斷路");
return new Result();
}
@Override
public Result plus2Service(Plus plus) {
Result result = new Result();
result.setCode(999);
result.setMessage("服務斷路");
return new Result();
}
}
@FeignClient(value = "testservice", fallback = TestServiceHystrix.class)
public interface TestService {
@RequestMapping(value = "/", method = RequestMethod.GET)
String indexService();
@RequestMapping(value = "/plus", method = RequestMethod.GET)
Result plusService(@RequestParam(name = "numA") int numA, @RequestParam(name = "numB") int numB);
@RequestMapping(value = "/plus", method = RequestMethod.POST, consumes = "application/json")
Result plusabService(Plus plus);
@RequestMapping(value = "/plus2", method = RequestMethod.POST)
Result plus2Service(@RequestBody Plus plus);
}
{
"code": 0,
"message": "hello",
"content": null,
"serviceName": "testservice",
"host": "localhost:8602"
}
{
"code": 999,
"message": "服務斷路"
}
至此完成Feign+Hystrix的熔斷。
歡迎關注公衆號! 公衆號回覆:
入羣
,掃碼加入咱們交流羣!