Netty源码阅读之如何将TCP的读写操作和指定线程绑定

原文链接: http://xueliang.org/article/detail/20200712234015993

前言

Netty线程模型中,对于一个TCP连接的读写操作,都是由一个单线程完成的,对于刚入门Netty的新手,这完全颠覆我们熟知的多线程能够加快处理速度,缩短处理时间的常规思路。

实际上,Netty采用了异步通信模式,一个IO 线程可以并发处理N 个客户端连接和读写操作,这从根本上解决了传统同步阻塞IO 一连接一线程模型,架构的性能、弹性伸缩能力和可靠性都得到了极大的提升。

源码阅读

Channel 注册到 Worker 线程组上

Netty源码阅读之如何将TCP的读写操作和指定线程绑定

调用 NioEventLoopGroupnext() 从 Worker 线程组中获取一个 eventLoop
Netty源码阅读之如何将TCP的读写操作和指定线程绑定

根据线程组个数不同,会调用 PowerOfTwoEventExecutorChooser 或者 GenericEventExecutorChoosernext() 方法,如果线程数是 2 的 N 次方,就选用 PowerOfTwoEventExecutorChooser 这个 EventLoop 选择类,使用位运算提高效率

Netty源码阅读之如何将TCP的读写操作和指定线程绑定

调用选取的 eventLoopregister() 方法,可以看到,将 this 也就是当前 EventLoop 当做参数传入 promise.channel().unsafe().register() 方法

Netty源码阅读之如何将TCP的读写操作和指定线程绑定

继续进到 promise.channel().unsafe().register 方法,到这里,终于将 eventLoop 赋值给了 Channel ,即 ChanneleventLoop 建立了绑定关系。

Netty源码阅读之如何将TCP的读写操作和指定线程绑定

但Channel还未与线程绑定,继续往下看,当我们平时在Handler里调用 ctx (即 ChannelHandlerContext 类对象)的 write() 时,实际是获取 ctxexecutor 执行写操纵事件,若未给 ctx 指定 executor ,则 ctx 会使用 对应的 channeleventLoop
Netty源码阅读之如何将TCP的读写操作和指定线程绑定

执行 eventLoopexecute() 方法

Netty源码阅读之如何将TCP的读写操作和指定线程绑定

进到 execute() 方法内,先通过调用 inEventLoop() 方法,判断当前线程是否是 eventLoop 绑定的那个线程

Netty源码阅读之如何将TCP的读写操作和指定线程绑定

如果不是,则可能 eventLoop 还没有绑定线程,则调用 startThread 方法创建一个线程

Netty源码阅读之如何将TCP的读写操作和指定线程绑定

最终调用 eventLoopdoStartThread() ,由 executor 指定创建线程的任务。

Netty源码阅读之如何将TCP的读写操作和指定线程绑定

到此,Channel – EventLoop – Thread 绑定在了一起,同时也能看出多个 Channel 可能绑定到 一个EventLoop上

总结

Netty将一个TCP连接和一个固定的线程绑定,不需要进行线程切换以及线程同步,即节省资源又提高吞吐效率,除此之外我们在阅读源码的过程中,从EventLoop的选取,根据不同的线程数,使用不同的轮询器,可以看出Netty对于高性能的极致追求。

原文链接: http://xueliang.org/article/detail/20200712234015993

原文 

https://segmentfault.com/a/1190000023196528

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » Netty源码阅读之如何将TCP的读写操作和指定线程绑定

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址