服务隔离
Hystrix实现服务隔离的思路:
- 使用命令模式(HystrixCommand/HystrixObservableCommand)对服务调用进行封装,使每个命令在单独线程中/信号授权下执行。
- 为每一个命令的执行提供一个小的线程池/信号量,当线程池/信号量已满时,立即拒绝执行该命令,直接转入服务降级处理。
- 为每一个命令的执行提供超时处理,当调用超时时,直接转入服务降级处理。
- 提供断路器组件,通过设置相关配置及实时的命令执行数据统计,完成服务监控数据分析,使得在命令执行中可以快速判断是否可以执行,还是执行服务降级处理。
1、线程池隔离与信号量隔离
线程池隔离:不同服务的执行使用不同的线程池,同时将用户请求的线程与具体业务执行的线程分开,业务执行的线程池可以控制在指定的大小范围内,从而使业务之间不受影响,达到隔离的效果。
信号量隔离:用户请求线程和业务执行线程是同一线程,通过设置信号量的大小限制用户请求对业务的并发访问量,从而达到限流的保护效果。
线程池隔离的有点:
- 应用系统会被完全保护起来,即使其中一个服务线程池满了,也不会影响到应用的其他服务。
- 当引入一个新的客户端的时候,如果发生问题,只会影响新的服务,并不会影响其他服务。
- 当一个失败的服务恢复正常时,系统会立即恢复正常的性能。
- 如果我们的应用系统一些参数配置错误,那么线程池的运行状况将会很快被检测出来,如延迟、超时、拒绝等。同时可以通过动态属性实时执行来处理纠正错误的参数配置。
- 如果服务的性能有变化需要调整,可以通过线程池指标动态属性修改,不会影响其他服务请求。
- Hystrix拥有专门的线程池可提供内置的并发功能,可以在同步调用之上构建异步外观模式。
线程池隔离的缺陷:增加了计算的开销,每个业务请求在执行的时候,会涉及请求排队、线程调度、上下文切换等处理。
2、服务隔离的颗粒度
服务隔离默认根据Command、Group和ThreadPool的命名来控制。
Group从业务逻辑上划分Command为一组
每个独立的外部依赖一个独立的Command,拥有唯一的Command名称。
每个独立的Command和ThreadPool是一对一关系。
服务隔离颗粒度控制策略:
- 服务分组+线程池:实现服务隔离的粗粒度控制,一个服务分组/系统配置一个隔离线程池即可。也可以不配置线程池名称或者配置相同的线程池名称。
- 服务分组+服务+线程池:实现服务隔离的细粒度控制,一个服务分组中的每一个服务配置一个隔离线程池。
- 混合实现:一个服务分组配置一个隔离线程池,然后对重要服务单独设置隔离线程池。
3、服务隔离配置
- execution.isolation.strategy:设置服务隔离策略。THREAD为线程池隔离,SEMAPHORE为信号量隔离。默认为THREAD。
- execution.isolation.thread.timeoutInMilliseconds:用来设置线程池隔离和信号量隔离两种策略的超时时间,单位为毫秒,默认值为1000ms。
- execution.isolation.semaphore.maxConcurrentRequests:设置使用信号量隔离时最的信号量大小。当请求达到或超过时,就会被降级处理,默认值为10。
- execution.timeout.enabled:是否开启业务服务超时处理,默认为true。
- execution.isolation.thread.interruptOnTimeout:当业务超时时是否中断线程,默认值为true。
- execution.isolation.thread.interruptOnCancel:取消时是否中断服务的执行,默认值为false。
通过Command构建Setter进行控制
通过注解方式进行配置