1. 程式人生 > >springcloud入門之斷路器Hystrix(四)

springcloud入門之斷路器Hystrix(四)

-c 例子 控制臺 介紹 tro you work 不同的 實現

什麽是斷路器

斷路器模式源於Martin Fowler的Circuit Breaker一文。“斷路器”本身是一種開關裝置,用於在電路上保護線路過載,當線路中有電器發生短路時,“斷路器”能夠及時的切斷故障電路,防止發生過載、發熱、甚至起火等嚴重後果。

  在分布式架構中,斷路器模式的作用也是類似的,當某個服務單元發生故障(類似用電器發生短路)之後,通過斷路器的故障監控(類似熔斷保險絲),向調用方返回一個錯誤響應,而不是長時間的等待。這樣就不會使得線程因調用故障服務被長時間占用不釋放,避免了故障在分布式系統中的蔓延。

Netflix Hystrix
  在Spring Cloud中使用了Hystrix 來實現斷路器的功能。Hystrix是Netflix開源的微服務框架套件之一,該框架目標在於通過控制那些訪問遠程系統、服務和第三方庫的節點,從而對延遲和故障提供更強大的容錯能力。Hystrix具備擁有回退機制和斷路器功能的線程和信號隔離,請求緩存和請求打包,以及監控和配置等功能。

  接下來我們就以一個簡單的例子,介紹一下Spring cloud Hystrix的使用

  首先在工程中添加spring cloud hystrix的依賴:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>

在工程的啟動類中加入@EnableCircuitBreaker開啟熔斷器功能

@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
public class Application {

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

    public static void main(String[] args){
        SpringApplication.run(Application.class,args);
    }
}

這裏也可以使用SpringCloud對應的@SpringCloudApplication註解來修飾啟動類,從代碼可以看到,該註解包含了其他的三個註解,也就以為著一個標準的SpringCloud程序包含著服務發現和熔斷機制。歡迎大家一起學習研究相關技術願意了解源碼的朋友直接求求交流分享技術:2147775633

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
public @interface SpringCloudApplication {
}

新增ComputeService類,在使用ribbon消費服務的函數上增加@HystrixCommand註解來指定回調方法

@Service
public class ComputeService {

    @Autowired
    private RestTemplate restTemplate;

    @HystrixCommand(fallbackMethod = "addServiceFallback")
    public String addService(){
        return restTemplate.getForEntity("http://COMPUTE-SERVICE/add?a=10&b=20", String.class).getBody();
    }

    public String addServiceFallback() {
        return "error";
    }
}

提供rest接口的Controller改為調用ComputeService的addService

@RestController
public class ConsumerController {

    @Autowired
    private ComputeService computeService;

    @RequestMapping(value = "/add", method = RequestMethod.GET)
    public String add() {
        return computeService.addService();
    }

}

驗證斷路器的回調

依次啟動eureka-server、compute-service、eureka-ribbon工程
訪問http://localhost:1111/可以看到註冊中心的狀態
訪問http://localhost:3333/add,頁面顯示:30
關閉compute-service服務後再訪問http://localhost:3333/add,頁面顯示:error
Feign使用Hystrix

  註意這裏說的是“使用”,沒有錯,我們不需要在Feigh工程中引入Hystix,Feign中已經依賴了Hystrix,我們可以在未做任何改造前,嘗試下面你的操作:

依次啟動eureka-server、compute-service、eureka-feign工程
訪問http://localhost:1111/可以看到註冊中心的狀態
訪問http://localhost:3333/add,調用eureka-feign的服務,該服務會去調用compute-service的服務,計算出10+20的值,頁面顯示30
關閉compute-service服務,訪問http://localhost:3333/add,我們獲得了下面的報錯信息

Whitelabel Error Page

This application has no explicit mapping for /error, so you are seeing this as a fallback.

Sat Jun 25 22:10:05 CST 2016
There was an unexpected error (type=Internal Server Error, status=500).
add timed-out and no fallback available.
如果您夠仔細,會發現與在ribbon中的報錯是不同的,看到add timed-out and no fallback available這句,或許您已經猜到什麽,看看我們的控制臺,可以看到報錯信息來自hystrix-core-1.5.2.jar,所以在這個工程中,我們要學習的就是如何使用Feign中集成的Hystrix。

  使用@FeignClient註解中的fallback屬性指定回調類

@FeignClient(value = "compute-service", fallback = ComputeClientHystrix.class)
public interface ComputeClient {

    @RequestMapping(method = RequestMethod.GET, value = "/add")
    Integer add(@RequestParam(value = "a") Integer a, @RequestParam(value = "b") Integer b);

}

創建回調類ComputeClientHystrix,實現@FeignClient的接口,此時實現的方法就是對應@FeignClient接口中映射的fallback函數。

@Component
public class ComputeClientHystrix implements ComputeClient {

    @Override
    public Integer add(@RequestParam(value = "a") Integer a, @RequestParam(value = "b") Integer b) {
        return -9999;
    }

}

再用之前的方法驗證一下,是否在compute-service服務不可用的情況下,頁面返回了-9999。

springcloud入門之斷路器Hystrix(四)