有关dubbo线程池溢出

dubbo集群中的provider角色,有两个线程池,一个是IO线程池,一个是业务线程池(默认200) 当业务线程并发比较高,或者业务处理变慢,业务线程池很容易满额,抛出“RejectedExecutionException: Thread pool is EXHAUSTED! ”异常。当然,前提是我们每给Provider的线程池配置等待Queue(队列)。 既然provider端已经抛出异常,表示自己受不了,但是consumer无动于衷,发出的请求还在等待,直到超时。这样极其容易导致整个系统的“雪崩”,因为它违背了fail-fast原则。 我们希望一旦Provider由于线程池被打满而无法收到请求,Consumer应该立即感知然后快速失败来释放线程。后来发现,完全是Dispatcher配置得不对,默认是all,我们应该配置成message。 调度器 Dispatcher 调度策略

  1. all 所有消息都派发到线程池,包括请求,响应,连接事件,断开事件,心跳等。
  2. direct 所有消息都不派发到线程池,全部在 IO 线程上直接执行。
  3. message 只有请求响应消息派发到线程池,其它连接断开事件,心跳等消息,直接在 IO 线程上执行。
  4. execution 只请求消息派发到线程池,不含响应,响应和其它连接断开事件,心跳等消息,直接在 IO 线程上执行。
  5. connection 在 IO 线程上,将连接断开事件放入队列,有序逐个执行,其它消息派发到线程池。

线程池 ThreadPool fixed 固定大小线程池,启动时建立线程,不关闭,一直持有。(缺省) cached 缓存线程池,空闲一分钟自动删除,需要时重建。 limited 可伸缩线程池,但池中的线程数只会增长不会收缩。只增长不收缩的目的是为了避免收缩时突然来了大流量引起的性能问题。 eager 优先创建Worker线程池。在任务数量大于corePoolSize但是小于maximumPoolSize时,优先创建Worker来处理任务。当任务数量大于maximumPoolSize时,将任务放入阻塞队列中。阻塞队列充满时抛出RejectedExecutionException。(相比于cached:cached在任务数量超过maximumPoolSize时直接抛出异常而不是将任务放入阻塞队列) 从上面可以看到所有的请求、响应、连接、断开都经过Dispatcher之手。 每种Dispatcher,都有对应的ChannelHandler,ChannelHandler将Handler的调动形成调用链。如果配置的是all,那么接下来上场的就是AllChannelHandler;如果配置的是message,那么接下来上场的就是MessageOnlyChannelHandler,这些ChannelHandler都是WrappedChannelHandler的子类,WrappedChannelHandler默认把请求、响应、连接、断开、心跳操作都交给Handler来处理。 AllChannelHandler覆盖了WrappedChannelHandler所有的关键操作,都将其放进到ExecutorService(这里指的是业务线程池)中异步来处理,但唯一没有异步操作的就是sent方法,该方法主要用于应答,但官方文档却说使用all时应答也是放到业务线程池的,写错了?这里,关键的地方来了,一旦业务线程池满了,将抛出执行拒绝异常,将进入caught方法来处理,而该方法使用的仍然是业务线程池,所以很有可能这时业务线程池还是满的,于是悲剧了,直接导致下游的一个HeaderExchangeHandler没机会调用,而异常处理后的应答消息正是HeaderExchangeHandler#caught来完成的,所以最后NettyHandler#writeRequested也没有被调用,Consumer只能死等到超时,无法收到Provider的线程池打满异常。 MessageOnlyChannelHandler只覆盖了WrappedChannelHandler的received方法,意味着只有请求处理会用到业务线程池,其他的非业务操作直接在IO线程池执行,这不正是我们想要的吗?所以使用message的Dispatcher,不会存在Provider线程池满了,Consumer却还在傻等的情况,因为默认IO线程池是无界的,一定会有线程来处理异常和应答(如果你把它设置成有界,那我也没啥好说的了)。

转载于:https://my.oschina.net/u/3045515/blog/3011361

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值