关于Hystrix整合ribbon调用其他服务时 首次进入回退
程序员文章站
2022-05-24 14:36:27
...
Hystrix简介
是由netflix开源的一个延迟或容错库,用于隔离访问远程系统、服务、或第三方库,防止级联失败,从而提升系统的容错性和可用性,实现方式如下:
包裹请求
使用HystrixCommand或HystrixobservableCommand包裹对依赖的调用逻辑,每一个命令都在独立的线程中执行。
跳闸机制
当某服务的错误率超过一定的阈值,Hystrix可以手动或自动的跳闸,停止请求该服务一段时间。
资源隔离
Hystrix为每一个依赖都维护了一个小型线程池(或信号量)如果该线程已满,发往该依赖的请求就会被立即拒绝,而不是排队等待,从而加速了失败判定。
监控
Hystrix可以近乎实时的监控运行指标和配置的变化,例如成功、失败、超时、以及被拒绝的请求等等。
回退机制
当请求失败、超时、被拒绝,或当断路器被打开的时候,执行回退逻辑。回退逻辑可有开发人员自行提供。
自我修复
断路器打开和一段时间后,会自动进入"半开"状态。正常情况下关闭-------->请求失败率达到阈值则打开,不再请阿牛依赖的服务------->一段时间后半开,允许一个请求访问依赖的服务,若成功则关闭断路器。
首次调用其他服务时直接访问量回退逻辑 二次访问时才正常访问
原有程序如下:
package com.xinq.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.xinq.entity.User;
@RestController
public class MoviesController {
private static final Logger LOGGER = LoggerFactory.getLogger(MoviesController.class);
@Autowired
public RestTemplate restTemplate;
@Autowired
public LoadBalancerClient loadBalancerClient;
//指定请求失败或超时的回退逻辑
@HystrixCommand(fallbackMethod = "fiindByIdFallback")
@GetMapping("/user/{id}")
public User findById(@PathVariable Long id) {
return this.restTemplate.getForObject("http://microservice-provider-user/" + id, User.class);
}
@GetMapping("/log-instance")
public void logUserInstance(){
ServiceInstance serviceInstance = this.loadBalancerClient.choose("microservice-provider-user");
LOGGER.info("{}:{}:{}",serviceInstance.getServiceId(),
serviceInstance.getHost(),serviceInstance.getPort());
}
public User fiindByIdFallback(Long id){
User user = new User();
user.setName("默认用户");
user.setId(-1L);
return user;
}
}
修复后:添加了commandProperties的超时时间
package com.xinq.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.xinq.entity.User;
@RestController
public class MoviesController {
private static final Logger LOGGER = LoggerFactory.getLogger(MoviesController.class);
@Autowired
public RestTemplate restTemplate;
@Autowired
public LoadBalancerClient loadBalancerClient;
//指定请求失败或超时的回退逻辑
@HystrixCommand(fallbackMethod = "fiindByIdFallback",commandProperties = {
//设置超时时间 超过则执行回退逻辑
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value="5000")
})
@GetMapping("/user/{id}")
public User findById(@PathVariable Long id) {
return this.restTemplate.getForObject("http://microservice-provider-user/" + id, User.class);
}
@GetMapping("/log-instance")
public void logUserInstance(){
ServiceInstance serviceInstance = this.loadBalancerClient.choose("microservice-provider-user");
LOGGER.info("{}:{}:{}",serviceInstance.getServiceId(),
serviceInstance.getHost(),serviceInstance.getPort());
}
public User fiindByIdFallback(Long id){
User user = new User();
user.setName("默认用户");
user.setId(-1L);
return user;
}
}
具体Hystrix的参数详解,可参考:https://blog.csdn.net/u013889359/article/details/80118884
上一篇: Ribbon调用
下一篇: Ribbon——超时与重试