Netty是如何处理新连接接入事件的?

本文详细分析了Netty如何处理新连接接入事件,包括Java NIO处理新连接的基本步骤,Netty的多线程Reactor架构,以及Netty服务端处理新连接的源码解读,重点探讨了Boss线程和Worker线程池的配合以及Selector的工作原理。

前言

前面的分析从Netty服务端启动过程入手,一路走到了Netty的心脏——NioEventLoop,又总结了Netty的异步API和设计原理,现在回到Netty服务端本身,看看服务端对客户端新连接接入的处理是怎么样的过程。

Java NIO处理新连接的编码模板

首先,对于新连接接入,从NIO层面有一个宏观的印象:

1、通过I/O多路复用器——Selector检测客户端新连接

对应到Netty,新连接通过服务端的NioServerSocketChannel(底层封装的JDK的ServerSocketChannel)绑定的I/O多路复用器(由NioEventLoop线程驱动)轮询OP_ACCEPT(=16)事件

2、轮询到新连接,就创建客户端的Channel

对应到Netty就是NioSocketChannel(底层封装JDK的SocketChannel)

3、为新连接分配绑定新的Selector

对应到Netty,就是通过线程选择器,从它的第二个线程池——worker线程池中挑选一个NIO线,在这个线程中去执行将JDK的SocketChannel注册到新的Selector的流程,将Netty封装的NioSocketChannel作为附加对象也绑定到该Selector

4、向客户端Channel绑定的Selector注册I/O读、或者写事件

对应到Netty,就是默认注册读事件,因为Netty的设计理念是读优先。以后本条Channel的读写事件就由worker线程池中的NIO线程管理

以上4步,其实就是对下面一段JDK NIO demo的抽象和封装,并解决了一些bug的过程,如下:

简单复习Netty的多线程Reactor架构

前面分析过NioEventLoopGroup和线程池对应,NioEventLoop实例和NIO线程对应,一个EventLoop实例将由一个永远都不会改变的Thread驱动其内部的run方法(和Runnable的run不是一个)。

简单说,Netty服务端创建的boss和worker就是两个线程池,对于一个服务器的端口,bossGroup里只会启动一个NIO线程用来处理该端口上的客户端新连接的检测和接入流程。

具体的说,Netty会在服务端的Channel的pipeline上,默认创建一个新连接接入的handler,只用于服务端接入客户端新连接,而workerGroup里有多个NIO线程(默认2倍的CPU核数个),负责已建立的Channel上的读写事件的检测、注册或者处理,等操作。当boss线程池的那一个NIO线程检测到新连接后就可以稍做休息(或者继续检测处理新连接),此时worker线程池就开始忙碌,如下图所示:

 

下面开始总结,boss线程和worker线程池之间是如何配合的。

再看JDK的select方法

在总结之前,个人认为有必要先回顾JDK的select,必须正确理解I/O多路复用器——Selector上所谓的轮询一次,返回就绪的Channel数目的真正意义,即这个过程有一个前提是自从上次select后开始计算的。这样干巴巴的解释可能不太清楚,下面举个例子,比如有两个已经建立的Channel,分别是A和B,而且A和B分别注册到了一个Selector上,接着在该Selector调用select():

  • 第一次调用select(),发现只有A有I/O事件就绪,select会立即返回1,然后处理之

  • 第二次调用select(),发现另一个通道B也有I/O事件就绪,此时select()还是返回1——即是自上次select后开始计算的

还有一点注意:如果第一次轮询后,对A没有做任何操作,那么就有两个就绪的Channel。

另外还要知道,select返回后可通过其返回值判断有没有Channel就绪,如果有就绪的Channel,那么可以使用selectedKeys()方法拿到就绪的Channel及其一些属性。下面看sel

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值