基本的容错模式有:
容错理念:
Hystrix实现了 超时机制和断路器模式。
Hystrix是Netflix开源的一个类库,用于隔离远程系统、服务或者第三方库,防止级联失败,从而提升系统的可用性与容错性。主要有以下几点功能:
Hystrix的工作原理可以可以参考官网的 How it Works 。如果要看中文版,可以参考: Hystrix工作原理 。
默认情况下hystrix使用线程池控制请求隔离
线程池隔离技术,是用 Hystrix 自己的线程去执行调用;而信号量隔离技术,是直接让 tomcat 线程去调用依赖服务。信号量隔离,只是一道关卡,信号量有多少,就允许多少个 tomcat 线程通过它,然后去执行。
信号量隔离主要维护的是Tomcat的线程,不需要内部线程池,更加轻量级。
| 优点 | 不足 | 适用 | |
|---|---|---|---|
| 信号量隔离 | 轻量,无额外开销 |
不支持任务排队和主动超时 不支持异步调用 |
受信客户 高扇出(网关) 高频高速调用(cache) |
| 线程池隔离 |
支持排队和超时 支持异步调用 |
线程调用会产生额外的开销 |
不受信客户 有限扇出 |
独立使用Hystrix可以参考 How To Use 。
如果想要中文,可以参考: Hystrix都停更了,我为什么还要学?
引入依赖 spring-cloud-starter-netflix-hystrix
。
在Service中:
@Service
public class GreetingService{
@HystrixCommand(fallbackMethod = "defaultGreeting")
public String getGreeting(String username){
return new RestTemplate()
.getForObject("http://localhost:9090/greeting/{username}",
String.class, username);
}
private String defaultGreeting(String username){
return "Hello User!";
}
}
在Application中:
@SpringBootApplication
@EnableCircuitBreaker
public class RestConsumerApplication{
public static void main(String[] args){
SpringApplication.run(RestConsumerApplication.class, args);
}
}
@EnableCircuitBreaker注释将扫描类路径以查找任何兼容的Circuit Breaker实现。
在集成Feign的基础上修改如下:
@FeignClient(name = "statistics-service", fallback = StatisticsServiceClientFallback.class)
public interface StatisticsServiceClient{
@RequestMapping(method = RequestMethod.PUT, value = "/statistics/{accountName}")
void updateStatistics(@PathVariable("accountName")String accountName, Account account);
}
@Component
@Slf4j
public class StatisticsServiceClientFallbackimplements StatisticsServiceClient{
@Override
public void updateStatistics(String accountName, Account account){
log.error("Error during update statistics for account: {}", accountName);
}
}
然后在配置文件中打开:
feign.hystrix.enabled=true
在一些场景中,简单的触发在 FeignClient 加入 Fallback 属性即可,而另外有一些场景需要访问导致回退触发的原因,那么这个时候可以在 FeignClient 中加入 FallbackFactory 属性即可;
@Component
public class WebErrorimplements FallbackFactory<ConsumerApi>{
@Override
public ConsumerApi create(Throwable cause){
return new ConsumerApi() {
@Override
public String getById(Integer id){
//针对不同异常返回响应
if(cause instanceof InternalServerError) {
System.out.println("InternalServerError");
return "远程服务报错";
}else if(cause instanceof RuntimeException) {
return "请求时异常:" + cause;
}else {
return "都算不上";
}
return null;
}
};
}
}
@FeignClient(name = "statistics-service", fallbackFactory = WebError.class)
| 配置项(前缀hystrix.command.*.) | 含义 |
|---|---|
| execution.isolation.strategy | 线程“THREAD”或信号量“SEMAPHORE”隔离(Default: THREAD) |
| execution.isolation.thread.timeoutInMilliseconds | run()方法执行超时时间(Default: 1000) |
| execution.isolation.semaphore.maxConcurrentRequests | 信号量隔离最大并发数(Default:10) |
| circuitBreaker.errorThresholdPercentage | 熔断的错误百分比阀值(Default:50) |
| circuitBreaker.requestVolumeThreshold | 断路器生效必须满足的流量阀值(Default:20) |
| circuitBreaker.sleepWindowInMilliseconds | 熔断后重置断路器的时间间隔(Default:5000) |
| circuitBreaker.forceOpen | 设true表示强制熔断器进入打开状态(Default: false) |
| circuitBreaker.forceClosed | 设true表示强制熔断器进入关闭状态(Default: false) |
| 配置项(前缀hystrix.threadpool.*.) | 含义 |
|---|---|
| coreSize | 使用线程池时的最大并发请求(Default: 10) |
| maxQueueSize | 最大LinkedBlockingQueue大小,-1表示用SynchronousQueue(Default:-1) |
| default.queueSizeRejectionThreshold | 队列大小阀值,超过则拒绝(Default:5) |
Hystrix有一个不错的可选功能是能够在仪表板上监视其状态。 为了启用它,我们将 spring-cloud-starter-hystrix-dashboard
和 spring-boot-starter-actuator
放入项目的pom.xml中。
然后添加 @EnableHystrixDashboard
注解。
启动应用程序后,将浏览器指向 http://localhost:8080/hystrix,输入“ hystrix.stream”的指标URL并开始监视。