dubbo 中使用 ThreadLocal 隐患

2020-10-31  本文已影响0人  欢乐时光欢乐你我

在 dubbo 中使用 ThreadLocal

在 Dubbo 中使用 ThreadLocal ,如果采用默认的设置,每次 Dubbo 调用结束,Dubbo 处理响应线程并不会被销毁, 而是归还到线程池中。而从 ThreadLocal 源码可以看出,每次我们设置的值其实会存在位于 Thread 中 ThreadLocalMap 变量中。

这就导致,下次如果 Dubbo 处理响应恰好继续使用到这个线程,该线程就能调用到上次响应中设置在 ThreadLocal 设置的值。这就引起内存泄露,可能还会导致业务上异常。其实并不止在 Dubbo 中,该案例还会发生在 web项目中,只要相关使用线程池的,都有可能发生。

dubbo 线程模型

dubbo的事件派发策略和线程池

dubbo基于netty----有5种派发策略:

dubbo 默认采用单一长连接加线程池方式处理调用。

默认采取 Dispatcher=all 的分发策略,所有消息都派发到线程池,包括请求,响应,连接事件,断开事件,心跳等。

线程池在缺省配置为固定大小线程池,启动时建立线程,不关闭,一直持有。

业务线程池:

Threadlocal 总结

使用 Threadlocal,我们需要注意几点:

  1. 使用 Threadlocal 需要跟使用相关流一样,需要最后显示调用其 remove 方法,清除其设置的值,防止引起内存泄露。
  2. 不能什么传参都使用 Threadlocal 在方法中上下传递,这样就会引起隐形耦合,而且相关代码并不好维护。
  3. 高并发中,我们可以使用 Threadlocal 代替同步锁,提高相关性能。

dubbo 默认线程池大小是200

调整线程池大小配置是

dubbo.protocol.threads = 5000
调整线程池类型配置是
dubbo.protocol.threadpool = cached
调整事件处理方式配置是
dubbo.protocol.dispatcher = message

或者
<dubbo:protocol name="dubbo" dispatcher="all" threadpool="fixed" threads="100" />

上一篇 下一篇

猜你喜欢

热点阅读