Java基础知识(三):Hystrix信号量 VS线程池

3. Hystrix信号量 VS线程池

信号量模式

接受请求和执行下游依赖在同一线程内完成,不存在线程上下文切换带来的性能开销,所以大部分场景应该选择信号量模式。

当一个接口依赖3个下游服务A、B、C,且3个服务返回数据互不依赖,这种情况采用信号量接口的耗时等于请求ABC服务耗时的总和。

为限制对下游依赖的并发量调用,可以配置Hystrix的execution.isolation.semaphore.maxConcurrentRequests,当并发请求数达到阈值时,请求线程可以快速失败,执行降级(计数器,tryAcquire、和release)。

线程池模式

用户请求会被提交到各自的线程中执行,把执行每个下游服务的线程分离,从而达到资源隔离的作用。当线程池来不及处理并且请求队列塞满时,新进来的请求将快速失败,可以避免依赖问题扩散。

在信号量模式提到的问题,对依赖的多个下游服务,通过线程池的异步操作,可以有效提高接口性能。

优势

  • 减少所依赖服务发生故障的影响面,比如A服务发生异常,导致请求大面积超时,对应的线程池被打满,这时并不影响B、C调用。
  • 如果接口性能有变动,可以方便调整线程池的参数或者超时时间,前提Hystrix参数实现动态代理

缺点

  • 请求再线程池中执行,肯定会带来任务调度、排队和上下文切换带来的开销
  • 因为涉及跨线程,那么存在ThreadLocal数据传递问题,比如主线程初始化的ThreadLocal变量,在线程池中无法获取。

Hystrix默认使用线程池,对于每个COmmand在初始化的时候,会创建一个对应的线程池。

你可能感兴趣的:(Java基础知识(三):Hystrix信号量 VS线程池)