关于springcloud线程池隔离和信号量隔离

信号量

信号量Semaphore是一个并发工具类,用来控制可同时并发的线程数,其内部维护了一组虚拟许可,通过构造器指定许可的数量,每次线程执行操作时先通过acquire方法获得许可,执行完毕再通过release方法释放许可。如果无可用许可,那么acquire方法将一直阻塞,直到其它线程释放许可。执行tryAcquire如果获取不不到就放弃。

线程池

线程池用来控制实际工作的线程数量,通过线程复用的方式来减小内存开销。线程池可同时工作的线程数量是一定的,超过该数量的线程需进入线程队列等待,直到有可用的工作线程来执行任务。

区别总结  在这里插入图片描述

信号量模式的使用场景

调用服务执行速度快,计算时间短,快速返回的场景,因为不支持设置超时,所以如果一旦阻塞,就必须等待socket连接超时
配置Hystrix的execution.isolation.semaphore.maxConcurrentRequests,当并发请求数达到阈值时,请求线程可以快速失败,执行降级。底层执行的是tryAcquire();

线程池模式的使用场景

hystrix中默认使用线程池隔离,在该模式下,用户请求会被提交到各自的线程池中执行,把执行每个下游服务的线程分离,从而达到资源隔离的作用。当线程池来不及处理并且请求队列塞满时,新进来的请求将快速失败,可以避免依赖问题扩散。
在信号量模式提到的问题,对所依赖的多个下游服务,通过线程池的异步执行,可以有效的提高接口性能。

优势

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

缺点

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

zuul中hystrix使用

Zuul默认是使用信号量隔离,并且信号量的大小是100,请求的并发线程超过100就会报错

可以调大该信号量的最大值来提高性能,配置如下:

zuul:
  semaphore:
    max-semaphores: 5000

也可以改为使用线程隔离,调大hystrix线程池线程大小,该线程池默认10个线程,配置如下:

zuul:
  ribbonIsolationStrategy: THREAD

hystrix:
  threadpool:
    default:
      coreSize: 100
      maximumSize: 400 #最大线程数量
      allowMaximumSizeToDivergeFromCoreSize: true #是否让maximumSize生效,false的话则只有coreSize会生效
      maxQueueSize: -1 #线程池的队列大小,-1代表使用SynchronousQueue队列

参考:http://t.zoukankan.com/chihirotan-p-11368520.html

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值