天天看點

SpringCloud-斷路器(Hystrix)

在微服務架構中,根據業務來拆分成一個個的服務,服務與服務之間可以互相調用(RPC),在Spring Cloud可以用Rest Template + Ribbon和Feign來調用。為了保證其高可用,單個服務通常會叢集部署。由于網絡原因或者自身的原因,服務并不能保證100%可用,如果單個服務出現問題,調用這個服務就會出現線程阻塞,此時若有大量的請求湧入,Servlet容器的線程資源會被消耗完畢,導緻服務癱瘓。服務與服務之間的依賴性,故障會傳播,會對整個微服務系統造成災難性的嚴重後果,這就是服務故障的雪崩效應。

為了解決這個問題,提出了斷路器模型

斷路器簡介

Netflix開源了Hystrix元件,實作了斷路器模式,SpringCloud對這一元件進行了整合。在微服務架構中,一個請求需要調用多個服務是非常常見的,如下圖

SpringCloud-斷路器(Hystrix)

較底層的服務如果出現故障,會導緻連鎖故障。當對特性的服務的調用的不可用達到一個門檻值(Hystric是5秒20此)斷路器将會被打開。

SpringCloud-斷路器(Hystrix)

斷路器打開後,可用避免連鎖故障,fallback方法可以直接傳回一個固定值

在ribbon使用斷路器

在pom檔案中加入spring-cloud-starter-hystrix的起步依賴

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

在程式的啟動類上添加注解@EnableHystrix啟用斷路器,如下

@EnableHystrix
@EnableDiscoveryClient
@SpringBootApplication
public class ServiceRibbonApplication {

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

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

改造HelloService類,在hiService方法上添加@HystrixCommand注解。該注解對該方法建立了熔斷器的功能,并指定了fallbackMethod熔斷方法,熔斷方法直接傳回了一個字元串,代碼如下

@Service
public class HelloService {

@Autowired
RestTemplate restTemplate;

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

測試

SpringCloud-斷路器(Hystrix)

此時斷掉eureka-client,再次測試

SpringCloud-斷路器(Hystrix)

說明當eureka-client工程不可用的時候,service-ribbon調用eureka-client的API接口時,會執行快速失敗,直接傳回一組字元串,而不是等待相應逾時,這很好的控制了容器的線程阻塞。

Feign中使用斷路器

Feign是自帶斷路器的,在D版本的Spring Cloud中,他沒有預設打開。需要在配置檔案中配置打開它,在配置檔案加以下代碼

feign:

hystrix:

enabled: true

隻需要在FeignClient的SchedualServiceHi接口的注解中加上fallback的指定類就行了:

@FeignClient(value = "eureka-client", fallback = SchedualServiceHiHystric.class)
public interface SchedualServiceHi {

@GetMapping("/hello")
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;
}
}      

測試正常狀态下

SpringCloud-斷路器(Hystrix)

停掉eureka-client,重試如下

SpringCloud-斷路器(Hystrix)

證明斷路器起作用了

Hystrix Dashboard(斷路器:Hystic儀表盤)

基于service-ribbon改造,Feign的改造一樣

pom中引入spring-cloud-starter-hystrix-dashboard的起步依賴

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

在啟動類中加入@EableHystrixDashboard注解,開啟hystrixDashbord

@EnableHystrixDashboard
@EnableHystrix
@EnableDiscoveryClient
@SpringBootApplication
public class ServiceRibbonApplication {

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

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

啟動如下

​​​http://localhost:8764/hystrix​​

SpringCloud-斷路器(Hystrix)

繼續閱讀