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

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

前言

在Netty的线程模型中,对于一个TCP连贯的读写操作,都是由一个单线程实现的,对于刚入门Netty的老手,这齐全颠覆咱们熟知的多线程可能放慢处理速度,缩短解决工夫的惯例思路。
实际上,Netty采纳了异步通信模式,一个IO 线程能够并发解决N 个客户端连贯和读写操作,这从根本上解决了传统同步阻塞IO 一连贯一线程模型,架构的性能、弹性伸缩能力和可靠性都失去了极大的晋升。

源码浏览

Channel 注册到 Worker 线程组上

调用 NioEventLoopGroupnext() 从 Worker 线程组中获取一个 eventLoop

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

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

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

但Channel还未与线程绑定,持续往下看,当咱们平时在Handler里调用 ctx (即 ChannelHandlerContext 类对象)的 write() 时,理论是获取 ctxexecutor 执行写操纵事件,若未给 ctx 指定 executor,则 ctx 会应用 对应的 channeleventLoop

执行 eventLoopexecute() 办法

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

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

最终调用 eventLoopdoStartThread() ,由 executor 指定创立线程的工作。

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

总结

Netty将一个TCP连贯和一个固定的线程绑定,不须要进行线程切换以及线程同步,即节俭资源又进步吞吐效率,除此之外咱们在浏览源码的过程中,从EventLoop的选取,依据不同的线程数,应用不同的轮询器,能够看出Netty对于高性能的极致谋求。

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

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理