共计 1234 个字符,预计需要花费 4 分钟才能阅读完成。
原文链接 :http://xueliang.org/article/detail/20200712234015993
前言
在 Netty 的线程模型中,对于一个 TCP 连贯的读写操作,都是由一个单线程实现的,对于刚入门 Netty 的老手,这齐全颠覆咱们熟知的多线程可能放慢处理速度,缩短解决工夫的惯例思路。
实际上,Netty 采纳了异步通信模式,一个 IO 线程能够并发解决 N 个客户端连贯和读写操作,这从根本上解决了传统同步阻塞 IO 一连贯一线程模型,架构的性能、弹性伸缩能力和可靠性都失去了极大的晋升。
源码浏览
将 Channel
注册到 Worker 线程组上
调用 NioEventLoopGroup
的 next()
从 Worker 线程组中获取一个 eventLoop
依据线程组个数不同,会调用 PowerOfTwoEventExecutorChooser
或者 GenericEventExecutorChooser
的 next()
办法,如果线程数是 2 的 N 次方,就选用 PowerOfTwoEventExecutorChooser
这个 EventLoop
抉择类,应用位运算提高效率
调用选取的 eventLoop
的 register()
办法,能够看到,将 this
也就是以后 EventLoop
当做参数传入 promise.channel().unsafe().register()
办法
持续进到 promise.channel().unsafe().register
办法,到这里,终于将 eventLoop
赋值给了 Channel
,即 Channel
与 eventLoop
建设了绑定关系。
但 Channel 还未与线程绑定,持续往下看,当咱们平时在 Handler 里调用 ctx
(即 ChannelHandlerContext
类对象)的 write()
时,理论是获取 ctx
的 executor
执行写操纵事件,若未给 ctx
指定 executor
,则 ctx
会应用 对应的 channel
的 eventLoop
执行 eventLoop
的 execute()
办法
进到 execute()
办法内,先通过调用 inEventLoop()
办法,判断以后线程是否是 eventLoop
绑定的那个线程
如果不是,则可能 eventLoop
还没有绑定线程,则调用 startThread
办法创立一个线程
最终调用 eventLoop
的 doStartThread()
,由 executor
指定创立线程的工作。
到此,Channel – EventLoop – Thread 绑定在了一起,同时也能看出多个 Channel 可能绑定到 一个 EventLoop 上
总结
Netty 将一个 TCP 连贯和一个固定的线程绑定,不须要进行线程切换以及线程同步,即节俭资源又进步吞吐效率,除此之外咱们在浏览源码的过程中,从 EventLoop 的选取,依据不同的线程数,应用不同的轮询器,能够看出 Netty 对于高性能的极致谋求。
原文链接 :http://xueliang.org/article/detail/20200712234015993