Spring Cloud (四):斷路器(Hystrix)

在微服務架構中, 根據業務來拆分成一個個的服務,服務與服務之間可以相互調用(RPC),在Spring Cloud可以用RestTemplate+Ribbon和Feign來調用。爲了保證其高可用,單個服務通常會集羣部署。由於網絡原因或者自身的原因,服務並不能保證100%可用,如果單個服務出現問題,調用這個服務就會出現線程阻塞,此時若有大量的請求涌入,程資源會被消耗Servlet容器的線完畢,導致服務癱瘓。服務與服務之間的依賴性,故障會傳播,會對整個微服務系統造成災難性的嚴重後果,這就是服務故障的“雪崩”效應。
爲了解決這個問題,業界提出了斷路器模型。
一、斷路器簡介
Netflix 開源了Hystrix組件,實現了斷路器模式,Spring Cloud 對這一組件進行了整合。在微服務中,一個請求調用多個服務是很常見的事情。如下圖:
在這裏插入圖片描述
較底層的服務如果出現故障,會導致連鎖故障。當對特定的服務的調用的不可用達到一個閥值(Hystric 是5秒20次) 斷路器將會被打開。
在這裏插入圖片描述
斷路打開後,可用避免連鎖故障,fallback方法可以直接返回一個固定值。
二、 準備工作
接着上篇文章的工程,啓動端口號爲8761 的 eureka-server 工程,啓動 端口號爲8762 的 eureka-client 工程。

三、在ribbon 使用斷路器
改造 eureka-ribbon 工程的代碼,首先在pom文件裏 加入依賴 spring-cloud-starter-netflix-hystrix

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

在啓動類上 加入註解 @EnableHystrix 開啓 Hystrix:

@EnableHystrix  // 引入斷路器模型
@EnableEurekaClient
@EnableDiscoveryClient
@SpringBootApplication
public class EurekaRibbonApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaRibbonApplication.class, args);
        System.out.println("================eureka-ribbon 啓動成功=================");
    }

    @Bean
    @LoadBalanced // 開啓負載均衡 功能
    RestTemplate restTemplate(){
        return new RestTemplate();
    }

}

改造 HelloService 類,在hiService方法上加上 @HystrixCommand 註解。該註解對該方法創建了熔斷器的功能,並指定了fallbackMethod熔斷方法,熔斷方法直接返回一個字符串,字符串爲 "hi, "+ name + “, sorry error!”;

@Service
public class HelloService {

    @Autowired
    private RestTemplate restTemplate;

    @HystrixCommand(fallbackMethod = "hiError")
    public String hiService(String name){
        return restTemplate.getForObject("http://EUREKA-CLIENT/hi?name="+name, String.class);
    }

    public String hiError(String name){
        return "hi, "+ name + ", sorry error!";
    }

}

啓動 eureka-ribbon 工程,訪問 http://localhost:8764/hi?name=lbh,瀏覽器 顯示: hi lbh ,i am from port:8762

當關閉eureka-client 工程時,再次訪問,瀏覽器 顯示: hi, lbh, sorry error!

此時,斷路器起作用了。當eureka-client 工程不可用時,eureka-ribbon 調用 eureka-client 的API接口時,會執行快速失敗,返回一組字符串,而不是等待響應超時,這很好控制了 容器的線程阻塞。

四、Feign 中使用斷路器
feign 是自帶斷路器功能的,在 D版本的spring cloud 之後,它沒有默認開啓,需要在配置文件中開啓:

feign:
  hystrix:
    enabled: true  # 開啓 feign 斷路器模式

基於 eureka-feign 工程進行改造,只需要在 FeignClient 的 SchedualServiceHi接口的註解中加上fallback的指定類就行了:

/**
*
* 注: 啓用斷路器 只需要在 @FeignClient()註解中加上 fallback 屬性就可以了,SchedualServiceHiHystric 實現改接口。
* Created by Advancer on 2019/1/17 10:46.
* auth: lbh
*/
@Component
@FeignClient(value = "eureka-client", fallback = SchedualServiceHiHystric.class)
public interface SchedualServiceHi {

    @RequestMapping(value = "/hi", method = RequestMethod.GET)
    String sayHiFromClientOne(@RequestParam(value = "name") String name);

}

SchedualServiceHiHystric需要實現SchedualServiceHi 接口,並注入到Ioc容器中,代碼如下:

@Component
public class SchedualServiceHiHystric implements SchedualServiceHi {

    @Override
    public String sayHiFromClientOne(String name) {
        return "sorry "+ name;
    }

}

啓動 eureka-feign 工程,瀏覽器 打開 http://localhost:8765/hi?name=lbh ,瀏覽器 顯示: hi lbh ,i am from port:8762
沒有啓動的情況下 顯示: sorry lbh

此時,斷路器起到作用了。

源碼下載地址:

https://github.com/JavaAdvancer/eurekademo

參考文章:

https://www.fangzhipeng.com/springcloud/2017/07/12/sc04-hystrix/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章