复杂的耗时的业务逻辑在Netty中该怎么处理?

发布于 2022-09-11 17:09:06 字数 786 浏览 11 评论 0

问题描述:

我们已知的一个或多个channel会注册到一个EventLoop上,这个EventLoop既要监听Channel上的事件,又要处理事件到来后业务逻辑(包括出站逻辑),也就是说Netty在同一个Channel上的handler调用是串行的,如下图,如果业务逻辑比较复杂,就会导致一些简单的事件得不到响应(也有可能是其他channel上的事件)。所以Netty不建议在handler处理复杂的业务逻辑,比如像数据库操作等等。那像这样的耗时逻辑在Netty中该怎么处理呢?

clipboard.png

我的思路

我的想法应该有两种处理方案

  1. 使用自定义的线程池,将需要处理的耗时逻辑封装成task丢到executor pool中,但是我们知道,线程多了并不是好事,会影响吞吐。
  2. 将这些任务丢到丢到那些空闲的EventLoop上,这样就能充分利用Netty的线程资源,但是这样的代码该怎么实现,有没有成熟的框架?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

鹿! 2022-09-18 17:09:06

请问你说的业务逻辑指的是你上文代码里 LoggingHandler里对应的channelRead方法里的逻辑吗?通过你的这种方式,最终执行channelRead方法里的逻辑的线程会是你传入的线程池里的线程?

何处潇湘 2022-09-18 17:09:06

进一步的学习应该是找到了答案吧!

EventLoop之所以称之为EventLoop,就是因为EventLoop需要循环的监听IO事件,任何耗时的逻辑都有可能导致IO事件不能被灵敏的响应,所以第二种方案是不可取的,虽然说Netty应用程序的一般准则是,尽可能的重用EventLoop,以减少线程创建带来的开销,但是前提是不能影响网络IO灵敏度。

所以处理复杂耗时的业务逻辑就需要一个专门的业务线程池,只要合理的设置业务线程池和事件循环线程池的线程数量,并不会对吞吐造成太大的影响。通常有两种方式实现业务线程池:

  1. ChannelHandler中,使用自定义的Java线程池。
  2. 借助Netty提供的业务线程池,ChannelPipeline有一些接收一个EventExecutorGroupadd()方法。如果有一个事件被传递给一个自定义的EventExecutorGroup,它将被包含在这个EventExecutorGroup中的某个EventExecutor所处理。Netty提供了一个叫DefaultEventExecutorGroup的默认实现。

clipboard.png

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文