目录
Hystrix是由Netflix开源的一款容错框架,包含隔离(线程池隔离、信号量隔离)、熔断、降级回退和缓存容错、缓存、批量处理请求、主从分担等常用功能。
Hystrix从以下四个方面来解决服务雪崩问题。
- 隔离(线程池隔离和信号量隔离):限制调用分布式服务的资源,使得某一个服务出现问题不会影响其他服务调用。
- 降级机制:在超时、资源不足时(线程或信号量)进行降级,在降级后可以配合降级接口返回托底数据。
- 熔断:当失败率达到阈值时,自动触发降级(如因网络故障、超时造成的失败率高等)。
- 缓存:提供了请求缓存、请求合并实现。
除此之外,它还支持实时监控、报警、控制。
Spring Cloud环境
笔者使用的Spring Cloud版本是2.4.2,spring-cloud-starter-openfeign版本是 3.0.0.
不同的Spring Cloud版本,对Hystrix的配置不一样。
在Feign中开启Hystrix
Feign本身支持Hystrix,默认是关闭Hystrix的,需要在配置文件中开启。但不同的Spring Cloud版本,开启Hystrix的配置不一样。
1、Spring Cloud 2020之前的版本
只需在配置文件中设置feign.hystrix.enabled=true
2、Spring Cloud 2020之后的版本
feign.hystrix.enabled=true无法解析,需要配置:feign.circuitbreaker.enabled=true
添加依赖和配置
pom文件
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
Spring Cloud2020之后,需要引入 spring-cloud-starter-netflix-hystrix 依赖。
application.properties配置
spring.application.name=Hystrix
server.port=9901
spring.cloud.consul.host=10.1.12.22
spring.cloud.consul.port=8500
#在Feign中开启 hystrix熔断
feign.circuitbreaker.enabled=true
#配置consul注册中心
spring.cloud.consul.discovery.instance-id=${spring.application.name}:${server.port}
#因为只是消费者,不提供服务,所以设置不需要注册到 consul 中
spring.cloud.consul.discovery.register=false
#logging.level.com.example.demo=DEBUG
实现Hystrix的容错回调
1、实现Feign接口
package com.example.demo.hystrix.feign;
import com.example.demo.hystrix.controller.HelloHystrix;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.context.annotation.Primary;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* 添加指定fallback类,在服务熔断的时候返回fallback类中的内容。
* name:远程服务名,即spring.application.name配置的名称
* 此类中的方法和远程服务中contoller中的方法名和参数需保持一致。
*/
@Primary
@FeignClient(name = "service-provider", fallback = HelloHystrix.class)
public interface MyFeignClient {
@RequestMapping(value = "/hello")
public String hello();
}
Hystrix支持“回退”的概念,如果熔断打开有错误,则执行默认动作。如果要启用回退功能,则需给@FeignClient设置fallback属性以实现回退的类名。
当Feign和Hystrix fallback一起使用时,如果存在多个同样类型的Bean,则会引起注解@Autowired不工作,因为没有一个Bean被标示为主(@Primary)的Bean,所以这里需要添加注解@Primary。
2、Hystrix回调类
package com.example.demo.hystrix.controller;
import com.example.demo.hystrix.feign.MyFeignClient;
import org.springframework.stereotype.Component;
@Component
public class HelloHystrix implements MyFeignClient {
@Override
public String hello() {
return "出现错误 ";
}
}
Hystrix回调类必须基于MyFeignClient接口,使得Feign的回退与Hystrix的回退一致。
3、启动类添加Feign支持
package com.example.demo.hystrix;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients
//@EnableDiscoveryClient
public class HystrixApplication {
public static void main(String[] args) {
SpringApplication.run(HystrixApplication.class, args);
}
}
4、控制器
package com.example.demo.hystrix.controller;
import com.example.demo.hystrix.feign.MyFeignClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@Autowired
MyFeignClient myFeignClient;
@RequestMapping("/hello")
public String index() {
return myFeignClient.hello();
}
}
测试fallback状态
1、开启Consul“服务中心”,service-provider 服务正常,访问http://localhost:9901/hello,可以正常获得服务的输出
2、只开启Consul“服务中心”,关闭service-provider,然后访问http://localhost:9901/hello,提升错误: