SpringCloud微服務系列(5): 服務容錯斷路器Hystrix

gobitan發表於2017-08-08
SpringCloud微服務系列(5): 服務容錯斷路器Hystrix
作者:家輝,日期:2017-08-08 CSDN部落格: http://blog.csdn.net/gobitan
摘要:在本系列的前四篇建立了一個高可用Eureka微服務註冊中心,一個hello服務,一個服務消費者ribbon-consumer。本文將介紹服務容錯斷路器Hystrix。

概述
使用者的一個請求可能在後端微服務中被拆分成多個服務,如果其中一個服務出現故障,如何進行隔離,儘可能地降低因為單個服務故障對整個系統的影響。這就是本文中的斷路器Hystrix。

第一步:在ribbon-consumer工程上增加對Hystrix的依賴
在pom.xml中新增對Hystrix的依賴,如下:
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
第二步:在主類中開啟斷路器功能
在主類中新增註解@EnableCircuitBreaker開啟斷路器功能。
也可用@SpringCloudApplication註解來替換如下三個註解:
@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker

第三步:改造服務消費方式
[1] 新增HelloService類
package cn.dennishucd.ribbonconsumer;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.client.RestTemplate;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;

public class HelloService {

    @Autowired
    RestTemplate restTemplate;
    
    @HystrixCommand(fallbackMethod = "helloFallback")
    public String helloService() {
        return restTemplate.getForEntity("http://hello-service/hello", String.class).getBody();
    }
    
    public String helloFallback() {
        return "error";
    }
}
通過為服務方法helloService增加@HystrixCommand註解,並定義服務降級回撥方法fallbackMethod,當服務失敗時就呼叫該方法。

[2] 修改ConsumerController類
package cn.dennishucd.ribbonconsumer;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class ConsumerController {
    @Autowired
    HelloService helloService;

    @RequestMapping(value = "ribbon-consumer", method = RequestMethod.GET)
    public String helloConsumer() {
        return helloService.helloService();
    }
}
修改後的類,通過呼叫前面的服務實現服務消費,而不是在Controller中直接實現。

第四步:修改ribbon-consumer的版本
為了與未加入斷路器的之前的ribbon-consumer區別,將它的版本由原來預設的0.0.1改為0.0.2。具體修改位置位於pom.xml中如下:
<groupId>cn.dennishucd</groupId>
<artifactId>ribbonconsumer</artifactId>
<version>0.0.2-SNAPSHOT</version>
<packaging>jar</packaging>
第五步:調測和驗證斷路器
準備工作:
[1] 啟動兩個eureka註冊中心:eureka1和eureka2; 啟動方法參考系列3.
[2] 啟動兩個hello-service服務註冊到註冊中心; 啟動方法參考系列4.

這時,分別做如下測試步驟:
[1] 啟動老版本的ribbon-consumer,即java -jar ribbonconsumer-0.0.1-SNAPSHOT.jar。連續兩次請求http://localhost:9000/ribbon-consumer服務,可以看到分別請求了啟動在8081和8082的hello-service服務,每次都返回”Hello World!”; 然後將8081埠的hello-service停掉,然後再連續兩次請求ribbon-consumer服務,可以看到一次返回500錯誤請求失敗,一次返回”Hello World!”; 
[2] 停止老版本,啟動新版本的ribbon-consumer,即java -jar ribbonconsumer-0.0.2-SNAPSHOT.jar。連續兩次請求http://localhost:9000/ribbon-consumer服務,可以看到分別請求了啟動在8081和8082的hello-service服務,每次都返回”Hello World!”; 然後將8081埠的hello-service停掉,然後再連續兩次請求ribbon-consumer服務,可以看到一次返回error,一次返回”Hello World!”; 這說明斷路器發揮了作用,當服務失敗時,自動返回自定義的回撥返回error。
[3] 經過測試,當8081的服務發生故障,過一會兒後(具體時間待確定)之後,ribbon每次請求都會成功。ribbon不會再將請求發往8081。因為,當一個服務發生故障後,註冊器週期性地會把發生故障的服務清理出去。此時,後臺的服務就只剩下8082了。

Hystrix還可以實現請求快取,後續再做研究。
疑問:服務故障後,到註冊中心主動清除的預設超時時間是多長?




相關文章