Hystrix 能使你的系统在出现依赖服务失效的时候,通过隔离系统所依赖的服务,防止服务级联失败,同时提供失败回退机制,更优雅地应对失效,并使你的系统能更快地从异常中恢复。
货船为了进行防止漏水和火灾的扩散,会将货仓分隔为多个,当发生灾害时,将所在货仓进行隔离就可以降低整艘船的风险。
熔断器就像家里的保险丝,当电流过载了就会跳闸,不过Hystrix的熔断机制相对复杂一些。
熔断器开关由关闭到打开的状态转换是通过当前服务健康状况和设定阈值比较决定的.
使用一个线程池来存储当前的请求,线程池对请求作处理,设置任务返回处理超时时间,堆积的请求堆积入线程池队列。这种方式需要为每个依赖的服务申请线程池,有一定的资源消耗,好处是可以应对突发流量(流量洪峰来临时,处理不完可将数据存储到线程池队里慢慢处理)。
使用一个原子计数器(或信号量)来记录当前有多少个线程在运行,请求来先判断计数器的数值,若超过设置的最大线程个数则丢弃改类型的新请求,若不超过则执行计数操作请求来计数器+1,请求返回计数器-1。这种方式是严格的控制线程且立即返回模式,无法应对突发流量(流量洪峰来临时,处理的线程超过数量,其他的请求会直接返回,不继续去请求依赖的服务)。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.netflix.hystrix</groupId> <artifactId>hystrix-core</artifactId> <version>1.5.12</version> </dependency> <dependency> <groupId>com.netflix.hystrix</groupId> <artifactId>hystrix-metrics-event-stream</artifactId> <version>1.5.12</version> </dependency> <dependency> <groupId>com.netflix.hystrix</groupId> <artifactId>hystrix-javanica</artifactId> <version>1.5.12</version> </dependency> 复制代码
@Configuration public class HystrixConfig { /** * 声明一个HystrixCommandAspect代理类,现拦截HystrixCommand的功能 */ @Bean public HystrixCommandAspect hystrixCommandAspect() { return new HystrixCommandAspect(); } } 复制代码
@Service public class HelloService { @HystrixCommand(fallbackMethod = "helloError", commandProperties = { @HystrixProperty(name = "execution.isolation.strategy", value = "THREAD"), @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000"), @HystrixProperty(name = "circuitBreaker.enabled", value = "true"), @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "2")}, threadPoolProperties = { @HystrixProperty(name = "coreSize", value = "5"), @HystrixProperty(name = "maximumSize", value = "5"), @HystrixProperty(name = "maxQueueSize", value = "10") }) public String sayHello(String name) { try { Thread.sleep( 15000 ); return "Hello " + name + " !"; } catch (InterruptedException e) { e.printStackTrace(); } return null; } public String helloError(String name) { return "服务器繁忙,请稍后访问~"; } } 复制代码
@SpringBootApplication @RestController public class HystrixSimpleApplication { @Autowired private HelloService helloService; public static void main(String[] args) { SpringApplication.run( HystrixSimpleApplication.class, args ); } @GetMapping("/hi") public String hi(String name) { return helloService.sayHello( name ); } } 复制代码
访问 http://localhost:80809/hi?name=zhangsan
curl -X GET -d 'name=zhangsan' http://localhost:8080/hi 复制代码
返回
服务器繁忙,请稍后访问~ 复制代码