Netty——启动流程
文章目录
- 1. 介绍
- 2. 启动流程
- 2.1 创建并初始化 Channel
- 2.2 注册 Channel 到 EventLoop
- 2.3 绑定端口并启动监听
- 2.4 处理新连接(主从 Reactor 模型)
- 3. 启动流程图
- 4. 总结
1. 介绍
Netty 服务器启动的核心入口是 ServerBootstrap
对象的 bind(int inetPort)
方法,本文将介绍 bind(int inetPort)
内部的执行流程。
2. 启动流程
2.1 创建并初始化 Channel
- 创建
NioServerSocketChannel
:- 通过反射实例化用户指定的
Channel
类型(默认为NioServerSocketChannel
),其无参构造函数会通过调用SelectorProvider
对象的openServerSocketChannel()
方法 创建底层 JDKServerSocketChannel
,并设置为非阻塞模式。 - 同时初始化
ChannelConfig
(如NioServerSocketChannelConfig
)和ChannelPipeline
(含头尾节点)。
- 通过反射实例化用户指定的
- 初始化
Channel
参数:通过option()
设置的参数(如SO_BACKLOG
)被应用到ChannelConfig
,但部分参数(如SO_BACKLOG
)需在 绑定端口时 通过 JDK 的ServerSocket
生效。
2.2 注册 Channel 到 EventLoop
- 选择
EventLoop
:从 BossGroup 的EventLoopGroup
中选择一个NioEventLoop
(主 Reactor)。 - 异步注册过程:
- 通过
register()
将Channel
注册到EventLoop
,该操作由EventLoop
线程 异步执行。若当前线程不是EventLoop
线程,则任务会被提交到任务队列。 - 注册成功后,
Channel
进入“已注册未激活”状态(尚未绑定端口)。
- 通过
- 初始化
ChannelPipeline
:注册完成后触发ChannelInitializer
对象的initChannel()
回调,执行以下操作:- 添加用户
Handler
:将用户通过handler()
设置的Handler
添加到Pipeline
中。 - 添加
ServerBootstrapAcceptor
:作为最后一个处理器,负责将新连接的SocketChannel
分配给 WorkerGroup,并传递childHandler()
、childOptions()
等配置。
- 添加用户
2.3 绑定端口并启动监听
- 绑定本地端口:
- 提交绑定任务到
EventLoop
的任务队列,由EventLoop
线程调用doBind()
:底层通过 JDK 的ServerSocketChannel
对象的bind()
方法绑定端口,此时SO_BACKLOG
等参数真正生效。 - 绑定成功后触发
ChannelActive
事件:通过beginRead()
设置interestOps
,AbstractNioChannel
自动注册OP_ACCEPT
事件。
- 提交绑定任务到
- 异步通知:绑定结果通过
ChannelFuture
通知,用户可通过sync()
阻塞等待 或addListener()
回调处理。
2.4 处理新连接(主从 Reactor 模型)
- 接受连接请求:主 Reactor 的
NioEventLoop
监听到OP_ACCEPT
事件后,调用NioServerSocketChannel
对象的doReadMessages()
方法,通过ServerSocketChannel
对象的accept()
方法创建SocketChannel
对象。 - 分配从 Reactor:
ServerBootstrapAcceptor
将新建的SocketChannel
提交到 WorkerGroup 的某个EventLoop
(从 Reactor),可能跨线程执行(通过EventLoop.execute()
)。 - 初始化客户端
Channel
:- 参数应用:
childOption()
和childAttr()
在注册时应用到客户端Channel
。 - 异步初始化:通过
childHandler()
中的ChannelInitializer
延迟添加用户 Handler,在EventLoop
线程中触发initChannel()
,避免阻塞主 Reactor。 - 事件注册:客户端
Channel
默认关注OP_READ
事件(可通过childHandler()
修改)。
- 参数应用:
3. 启动流程图
4. 总结
Netty 服务器的启动流程主要体现在 ServerBootstrap
对象的 bind(int inetPort)
方法里,分为四个部分:
- 创建并初始化
Channel
。 - 注册
Channel
到EventLoop
。 - 绑定端口并启动监听。
- 使用主从 Reactor 模型处理事件。