这节主要学习如何在使用Feign消费服务时使用Hystrix,首先认识下什么是Hystrix,Hystrix解决了什么问题,最后介绍如何使用Hystrix Dashboard监控熔断器的状态。
1、什么是Hystrix
在分布式系统中,服务于服务之间存在依赖关系错综复杂,服务服务出现故障是无可避免的,如果出现服务故障务必会导致依赖于他们的其他服务会出现远程调度的线程阻塞,Hystrix提供了熔断器的功能,能够阻止分布式系统中出现联动故障,避免系统出现雪崩现象
2、Hystrix的设计原则
a、防止单个服务的故障耗尽整个服务的容器(Tomcat)的线程资源;
b、快速失败异常处理机制,某个服务出现故障,则调用该服务的请求会立即失败,而不是一直等待;
c、提供fallback方案,请求出现故障时,提供个性化的回退方案;
d、提供熔断器监控组件Hystrix Dashboard,可以监控熔断器状态。
3、在Feign上使用Hystrix
Feign的启动依赖自带了Hystrix的依赖,所以无需额外引入任何依赖,需要在配置文件中增加如下配置:
feign:
#开启Hystrix
hystrix:
enabled: true
增加一个异常处理类,必须实现@FeignClient修饰的接口,代码如下:
package com.hzlitai.eurekafeignclient.service.impl;
import com.hzlitai.eurekafeignclient.service.EurekaFeignClient;
import org.springframework.stereotype.Component;
@Component
public class DoHystrix implements EurekaFeignClient {
@Override
public String sayHiFromEurekaClient(String name) {
return "Sorry,"+name+" is error!";
}
}
然后在@FeignClient注释的fallback配置上添加异常处理类,代码如下:
package com.hzlitai.eurekafeignclient.service;
import com.hzlitai.eurekafeignclient.configuration.FeignConfig;
import com.hzlitai.eurekafeignclient.service.impl.DoHystrix;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
//value值为服务名称
@FeignClient(value = "eureka-client",configuration = FeignConfig.class,fallback = DoHystrix.class)
public interface EurekaFeignClient {
@GetMapping("/hi")
String sayHiFromEurekaClient(@RequestParam(value = "name") String name);
}
访问http://localhost:8767/sayHi?name=zhuheliang,然后关掉eureka-client,重新访问就可看到异常处理信息。
4、使用Hystrix Dashboard监控熔断器的状态
引入三个关键的依赖spring-boot-starter-actuator、spring-cloud-starter-netflix-hystrix、spring-cloud-starter-netflix-hystrix-dashboard,注意这里的依赖包都是启动依赖包,Feign自带的Hystrix依赖包不是启动依赖包。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
程序的启动类增加注解和servlet信息,代码如下:
package com.hzlitai.eurekafeignclient;
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.context.annotation.Bean;
@EnableFeignClients
@EnableEurekaClient
@EnableHystrix
@EnableHystrixDashboard
@EnableCircuitBreaker
@SpringBootApplication
public class EurekaFeignClientApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaFeignClientApplication.class, args);
}
//解决Dashboard无法访问/actuator/hystrix.stream的问题
@Bean
public ServletRegistrationBean getServlet() {
HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
registrationBean.setLoadOnStartup(1);
registrationBean.addUrlMappings("/actuator/hystrix.stream");
registrationBean.setName("HystrixMetricsStreamServlet");
return registrationBean;
}
}
如果使用localhost进行访问的,需要在配置文件application.yml配置proxyStreamAllowList,代码如下:
hystrix:
dashboard:
proxy-stream-allow-list: "localhost"
最后输入http://localhost:8767/hystrix,进入界面:
依次输入http://localhost:8767/actuator/hystrix.stream、2000、hzlitai(随意输入),点击Monitor Stream,即可看到监控信息(如果一直显示loading,就用调用接口访问下):
5、使用Turbine聚合监控
由于每个服务都有一个Hystrix Dashboard主页,当服务器个数很多时,监控就非常不方便,Turbine用于聚合多个Hystrix Dashboard,将多个监控画面放在一个页面展示,进行集中监控。
新建一个eureka-monitor-client的Module工程(Spring Initializr),依赖勾选Spring Web,Eureka Discovery Cient,Hystrix,Hystrix Hystrix DashBoard和Turbine。
配置application.yml,代码如下:
spring:
application:
name: service-turbine
server:
port: 8768
turbine:
app-config: eureka-ribbon-client,eureka-feign-client
cluster-name-expression: new String("default")
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
依赖文件pom源码如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.hzlitai</groupId>
<artifactId>eureka-memo</artifactId>
<version>1.1-SNAPSHOT</version>
</parent>
<groupId>com.hzlitai</groupId>
<artifactId>eureka-turbine</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eureka-turbine</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-turbine</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
主启动文件增加注解,源码如下:
package com.hzlitai.eurekaturbine;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.turbine.EnableTurbine;
@EnableTurbine
@EnableEurekaClient
@SpringBootApplication
public class EurekaTurbineApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaTurbineApplication.class, args);
}
}
然后依次启动eureka-server、eureka-client、eureka-ribbon-client、eureka-feign-client和eureka-turbine实例,启动成功后,依次访问:http://localhost:8766/sayHi?name=zhuheliang、http://localhost:8767/sayHi?name=zhuheliang,然后访问:http://localhost:8766/hystrix/,进入页面后,依次输入:http://localhost:8768/turbine.stream、2000、monitor,最后生成即可。