Hystix是Netflix开源的一个延迟和容错库,用于隔离访问远程服务、第三方库,防止出现级联失败。
Hystix(解决雪崩问题(服务故障,导致大量请求无法即时响应):线程隔离、服务熔断:(m次请求,n%失败(超时或异常)则熔断(打开断路器),休眠p秒;然后响应部分请求(半开断路器),如果都成功,就响应全部请求(关闭断路器),否则再次休眠p秒)。
缺省是5秒内20次调用失败,就会启动熔断机制。
当服务繁忙时,如果服务出现异常,不是粗暴的直接报错,而是返回一个友好的提示,虽然拒绝了用户的访问,但是会返回一个结果。
系统特别繁忙时,一些次要服务暂时中断,优先保证主要服务的畅通,一切资源优先让给主要服务来使用,在双十一、618时,京东天猫都会采用这样的策略。 服务降级:优先保证核心服务,非核心服务不可用或弱可用。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
@SpringCloudApplication已经包括了 @EnableCircuitBreaker。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
public @interface SpringCloudApplication {
}
@Component
public class UserDao {
@Autowired
private RestTemplate restTemplate;
private static final Logger logger = LoggerFactory.getLogger(UserDao.class);
@HystrixCommand(fallbackMethod = "queryUserByIdFallback")
public User queryUserById(Long id){
long begin = System.currentTimeMillis();
String url = "http://user-service/user/" + id;
User user = this.restTemplate.getForObject(url, User.class);
long end = System.currentTimeMillis();
// 记录访问用时:
logger.info("访问用时:{}", end - begin);
return user;
}
public User queryUserByIdFallback(Long id){
User user = new User();
user.setId(id);
user.setName("用户信息查询出现异常!");
return user;
}
}
@HystrixCommand(fallbackMethod="queryUserByIdFallback")
:声明一个失败回滚处理函数queryUserByIdFallback,当queryUserById执行超时(默认是1000毫秒),就会执行fallback函数,返回错误提示。
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMillisecond: 6000 # 设置hystrix的超时时间为6000ms
// @HystrixCommand
// 自定义超时时长3秒,默认1秒:com.netflix.hystrix.HystrixCommandProperties的private static final Integer default_executionTimeoutInMilliseconds = 1000;
// name在com.netflix.hystrix.HystrixCommandProperties中找
// 可在yml中配置消费的全体服务、某些服务或某些方法的超时时长
// @HystrixCommand(commandProperties = {
// @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")
// })
// 8次请求,60%失败(超时或异常)则熔断(打开断路器),休眠10秒;然后响应部分请求(半开断路器),如果都成功,就响应全部请求(关闭断路器),否则再次休眠10秒
// @HystrixCommand(commandProperties = {
// @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "8"),
// @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"),
// @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60")
// })
hystrix:
command:
# 默认
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 4000 # 超时则服务降级,服务超时达到一定比例,则熔断
# 服务
user-service:
execution:
isolation:
thread:
timeoutInMilliseconds: 4000
# 服务接口
queryById:
execution:
isolation:
thread:
timeoutInMilliseconds: 4000