基本的容错模式有:
容错理念:
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并开始监视。