什么是Hystrix
在微服务架构中,每个服务运行在独立的进程中,服务之间通过服务治理来实现服务的发布和订阅,通过远程服务调用的方式消费服务。
如果因为网络原因或者服务自身问题出现调用故障或延迟,则会直接导致调用方对外服务也出现延迟,若此时调用方的请求不断积压,就会导致服务的瘫痪。
为了解决这样的问题,产生了断路器等一系列服务保护机制。断路器是一种开关装置,当线路过载时它能够及时的切断故障线路,避免更严重的后果。
在微服务中,如果某个服务单元发生故障,则会中断对该服务的调用并执行一个回调函数进行响应,避免长时间的等待而导致服务的瘫痪。
Spring Cloud Hystrix 实现了断路器、线程隔离等一系列服务保护功能,它也是基于Netflix的Hystrix实现的。
Hystrix实现服务降级——基于RestTemplate
Hystrix是作用在服务的消费者上,所以需要在服务的消费端使用。
- 添加Hystrix依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
- 在启动类添加@EnableCircuitBreaker注解启用断路器
- 编写服务调用代码
package com.wxw.example.springcloudconsumer.controller.hystrix;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class HystrixController {
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
@Autowired
private RestTemplate restTemplate;
@RequestMapping("/hystrix/hello")
@HystrixCommand(fallbackMethod = "fallback")
public String hystrixTest(){
String result = restTemplate.getForObject("http://localhost:8080/hello",String.class);
return result;
}
public String fallback(){
return "系统繁忙,请稍后!!!";
}
}
-
如果被调用的服务出现故障则会执行回调fallback实现服务的降级。
-
如果一个类中实现降级的内容都一样,则可以在类头部添加@DefaultProperties注解,避免给每个方法都添加相同的注解。
@DefaultProperties(defaultFallback = "fallback")
- Hystrix执行降级操作时默认是服务响应时间超过1秒,可以通过配置指定时间
@HystrixCommand(commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "5000")
})
其他更多的配置可以通过HystrixCommandProperties类查看
Hystrix实现服务降级——基于OpenFeign
- 在配置文件中启用Hystrix
# 启用Hystrix
feign.hystrix.enabled=true
- 创建一个类,实现调用服务的接口,重写接口中的方法,在方法中添加回调的内容,同时在类头部加上@Component注解
package com.wxw.example.springcloudconsumer.controller;
import com.wxw.example.springcloudconsumer.pojo.User;
import org.springframework.stereotype.Component;
@Component
public class HystrixHelloControllerFeign implements IHelloControllerFeign {
@Override
public String hello() {
return "调用hello方法触发了Hystrix降级";
}
@Override
public String helloUser(User user) {
return "调用helloUser方法触发了Hystrix降级";
}
}
- 在服务调用接口中补充注解,指定刚刚创建的类
package com.wxw.example.springcloudconsumer.controller;
import com.wxw.example.springcloudconsumer.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
@FeignClient(name = "provider-service",fallback = HystrixHelloControllerFeign.class)
public interface IHelloControllerFeign {
@RequestMapping("/hello")
String hello();
@RequestMapping(value = "/helloUser")
String helloUser(@RequestBody User user);
}
Hystrix熔断机制
默认情况下,如果某个服务10秒内,20个请求中出现50%的请求失败,则开启熔断开关。在之后的5秒内,客户端发起的所有请求都不会到服务端,而是直接执行fallback()方法。5秒之后,客户端会尝试发起一个请求到服务端,如果请求正常,则关闭熔断开关恢复正常。
以上标记的参数都是可以配置的。
circuitBreaker.requestVolumeThreshold:最小请求次数,默认20个
circuitBreaker.sleepWindowInMilliseconds:开启熔断开关后系统睡眠时间,默认5秒
circuitBreaker.errorThresholdPercentage:请求失败数占比,默认50%
Hystrix隔离机制
Hystrix提供两种隔离机制,可以通过execution.isolation.strategy参数设置
- 线程池隔离(THREAD)
- 信号量隔离(SEMAPHORE)