微服务中服务之间的相互依赖性错综复杂,一个网络请求通常需要调用多个服务实例才能完成。如果一个服务不可用,如网络延迟或故障,会影响依赖于这个服务的其它服务,最后导致整个系统处于瘫痪的状态。为解决这种雪崩效应,引进熔断组件Hystrix,当出现故障后会自动剔除服务实列。Hystrix除了一些基本的熔断器,还能实现服务降级、服务限流的功能,并提供了界面展示健康状态的功能。本章讲诉如何使用RestTemplate和Feign消费服务是使用Hystrix,并介绍Hystrix的工作原理。
Hystrix的设计原则
- 防止单个服务的故障耗尽整个服务的Servlet容器(如Tomcat)的线程池资源。
- 快速失败机制,如果某个服务出现了故障,则调用该服务的请求快速失败,而不是线程等待。
- 提供回退方案,在请求发生故障时,提供设定好的回退方案。
- 使用熔断器机制,防止故障扩散到其他的服务。
- 提供熔断器的监控组件Hystrix Dashboard,可以实时监控熔断器的状态。
Hystrix的工作机制
当服务的某个API接口的失败次数在一定时间内小于设定的阈值时,熔断器处于关闭状态,该API接口正常提供服务。当该API接口处理请求的失败次数大于设定的阈值时,Hystrix判定该API接口出现了故障,打开熔断器,这时该API接口会执行快速失败的逻辑,不执行业务逻辑,请求的线程不会处于阻塞状态。处于打开状态的熔断器在一定时间后会处于半打开状态,并将一定数量的请求执行正常逻辑,剩余的请求会执行快速失败。若执行正常逻辑的请求失败了,则熔断器继续打开,若成功了,则熔断器关闭。这样熔断器就具有了自我修复的功能。
在RestTemplate上使用熔断器
本章案例在前面章节的案例基础之上进行改造。在讲述ribbon章节时,eureka-ribbon-client工程中我们使用RestTemplate调用了eureka-client的“/hi”接口,并用Ribbon做了负载均衡,现在在此基础上加Hystrix熔断器的功能。
- 添加Hystrix的起步依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
- 在启动类上添加@EnableHystrix注解开启Hystrix的熔断器功能。
@SpringBootApplication
@EnableEurekaClient
@EnableHystrix
@EnableHystrixDashboard
public class EurekaRibbonClientApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaRibbonClientApplication.class, args);
}
}
- 修该RibbonService的代码,在方法中加上@HystrixCommand注解。有了@HystrixCommand方法就用Hystrix熔断器的功能,其中,fallbackMethod为处理回退逻辑的方法,在本例中,直接返回了一个字符串。在熔断器打开的状态下,会执行回退逻辑。回退逻辑最好是返回一些静态的字符串,不需要处理复杂的逻辑,也不需要远程调用其它的服务,这样能执行快速失败,释放线程资源。如果在回退逻辑中一定要调用远程服务,最好在远程调度其它的服务时,也加上熔断器。
public class RibbonServiceHystrix {
@Autowired
private RestTemplate restTemplate;
@HystrixCommand(fallbackMethod = "hiError")
public String hiFromClient() {
return restTemplate.getForObject("http://eureka-client/hi?name=dzy", String.class);
}
public String hiError(){
return "error";
}
}
- 启动eureka-server和eureka-ribbon-client。此时没有启动eureka-client,所以eureka-ribbon-client肯定是访问不通eureka-client接口的。此时访问http://localhost:8765/hi,浏览器会显示回退逻辑返回的错误字符串。做到了快速失败,线程不在阻塞。
在Feign上使用熔断器
- 之前介绍Feign提到本身已经集成了熔断器的功能,Feign的起步依赖已经引入了Hystrix的依赖,所以不需要在pom文件中添加Hystrix的依赖。只需要在配置文件中开启Hystrix功能即可。
feign:
hystrix:
enabled: true
- 在声明式接口中的@FeignClient注解上添加fallback属性来配置快速失败的处理类。该处理类作为Feign熔断器的逻辑处理类,必须实现被@FeignClient修饰的接口,最后需要以Spring Bean的形式注入IoC容器中。
@FeignClient(value = "eureka-client", configuration = FeignClientConfig.class,fallback = HiFailBack.class)
public interface HiFeignClient {
@GetMapping("/hi")
String hi(@RequestParam(value = "name") String name);
}
@Component
public class HiFailBack implements HiFeignClient {
@Override
public String hi(String name) {
return "hystrix error";
}
}
- 启动eureka-server,eureka-feign-client,此时没有启动eureka-client,所以eureka-feign-client接口调用eureka-client的接口是肯定连接不通的。在浏览器访问eureka-feign-client接口,浏览器会出现配置的错误字符串,说明实现了快速失败。
使用Hystrix Dashboard监控熔断器的状态
Hystrix Dashboard 是监控Hystrix的熔断状况的一个组件,提供了数据监控和友好的图形化展示界面。
在RestTemplate中使用Hystrix Dashboard
在eureka-ribbon-client的基础上改造。
- 在pom文件中加上Actuator的起步依赖,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>
- 在启动类上加上@EnableHystrixDashboard开启Hystrix Dashboard的功能。
@SpringBootApplication
@EnableEurekaClient
@EnableHystrix
@EnableHystrixDashboard
public class EurekaRibbonClientApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaRibbonClientApplication.class, args);
}
}
- 依此启动eureka-server,eureka-client和eureka-ribbon-client(我的端口为8765),确定两个eureka client已经注册到了eureka server中。
在浏览器访问http://localhost:8765/hystrix,会出现Hystrix Dashboard的界面。
image.png
在界面中依此填写http://localhost:8765/hystrix.stream,200,forezp(任意填写),点击“monitor”,进入界面
image.png
监控图中用圆点来表示服务的健康状态,健康度从100%-0%分别会用绿色、黄色、橙色、红色来表示。 另外,这个圆点也会随着流量的增多而变大。 监控图中会用曲线(圆点旁边)来表示服务的流量情况,通过这个曲线可以观察单个接口的流量变化/趋势。对应的指标含义如下
image.png
在feign中使用Hystrix Dashboard
- 添加Actuator,Hystrix,Hystrix Dashboard的起步依赖。这里需要注意,既然Feign自带Hystrix,那为什么还需要引入spring-cloud-starter-hystrix?这是因为Feign自带的是Hystrix的依赖不是Hystrix起步依赖。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
- 在启动类上加上@EnableHystrixDashboard开启Hystrix Dashboard的功能。
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
@EnableHystrixDashboard
@EnableHystrix
public class EurekaFeignClientApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaFeignClientApplication.class, args);
}
}
只需要上述两步就可以在Feign中开启Hystrix Dashboard的功能。
使用Turbine聚合监控
在使用Hystrix Dashboard组件监控服务的熔断状况时,每个服务都有一个Hystrix Dashboard主页,当服务数量很多时,监控非常不方便。为了同时监控多个服务的熔断器的状况,Netflix开源了Hystrix另一个组件Turbine。Turbine用于聚合多个Hystrix Dashboard,将多个Hystrix Dashboard组件的数据放在一个页面上展示,进行集中监控。
- 新建一个Module工程,取名为turbine-server,在pom中添加turbine,actuator,test的起步依赖。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-turbine</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
- 在配置文件application加上相关的配置。
server:
port: 8770
spring:
application:
name: turbine-server
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
management:
security:
enabled: false
turbine:
app-config: eureka-ribbon-client,eureka-feign-client
cluster-name-expression: new String("default")
aggregator:
clusterConfig: default
其中turbine.app-config配置了需要监控的服务名,turbine.cluster-name-expression默认为服务器的集群,此时用默认的即可。turbine.aggregator.clusterConfig可以不写,因为默认就是default。
- 启动类上添加@EnableTurbine注解,启动Turbine功能
@SpringBootApplication
@EnableEurekaClient
@EnableTurbine
public class TurbineServerApplication {
public static void main(String[] args) {
SpringApplication.run(TurbineServerApplication.class, args);
}
}
- 启动eureka-server,eureka-ribbon-client,eureka-feign-client,turbine-server
在浏览器访问http://localhost:8765/hystrix,在这个界面为eureka-ribbon-client的
Hystrix Dashboard界面(用其它服务的Hystrix Dashboard也可,只要监控流为turbine服务器地址就行,但在项目中只会启用一个服务的Hystrix Dashboard),在界面中依此输入监控流的Url地址http://localhost:8770/turbine.stream,监控时间间隔为2000毫秒和title,点击“monitor”,可以看到如下界面。
image.png
可以看到这个界面同时聚合了eureka-ribbon-client和eureka-feign-client的Hystrix Dashboard。
总结
在这一章学习了熔断器Hystrix,其中包括什么是Hystrix,Hystrix的工作原理,TestTemplate、Feign结合Hystrix的使用。最后介绍使用图形化监控组件Hystrix Dashboard,以及监控聚合组件Turbine。在下一章中介绍路由网关Zuul。
PS:项目github地址:https://github.com/dzydzydzy/spring-cloud-example.git
网友评论