Netty启动源码解析

概念

1.handler

源码是这么解析它的 the ChannelHandler to use for serving the requests.

意思是用于服务请求,也就是主reactor线程处理的handler.

重要的实现类

ServerBootstrapAcceptor

这个类在ServerBootstrap启动中有默认加到主reactor的pipeline(默认的pipeline是DefaultChannelPipeline,请记住这个实现类)里。

LoggingHandler

netty提供的一个记录日志handler

childHandler

Set the ChannelHandler which is used to serve the request for the Channel's. 文档指出这是一个处理channel请求的handler

启动流程

1.初始化serverSocket

1.1 创建ServerSocketChannel

具体实现由启动时channel参数决定

1.2 初始化channel

向serverSocketChannel加入ChannelInitializer实例, 在该实例回调中向pipeline中加入启动时加入的handler实例 (上文提到的handler参数)和ServerBootstrapAccptor实例

1.3 从bossGroup中取出一个线程来处理channel注册,并注册到线程自己的selector上

  1. #启动bossGroup线程,在线程里处理事件循环和队列任务,具体逻辑不深入。
  2. 这里注册到selector的感兴趣事件为0,并没有将accept事件加入到selector中,这里只有启动,和处理任务队列里的数据,只有后面执行bind方法后才能真正处理网络事件。
  3. 从这里可以得知,我们在许多的bossgroup中取出一个,如果是设定了多个bossGroup线程,并且只绑定到一个网卡,其它线程可能不会被使用,这个问题需要我们思考。

2.doBind0绑定端口

2.1 调用channel的bind方法

2.2 调用channel里的pipeline.bind方法

2.3 从尾结点开始找到所有OUT的handler,并调用bind方法

在header节点会调用unsafe.bind,这里才是netty真正实现的方法

2.3.1 NioMessageUnsafe.bind
2.3.2 doBind绑定网卡和端口
2.3.3 触发fireChannelActive事件
scss 复制代码
if (!wasActive && isActive()) {
    invokeLater(new Runnable() {
        @Override
        public void run() {
            pipeline.fireChannelActive();
        }
    });
}

2.3.4 从头节点执行active方法

scss 复制代码
// 找到所有inBound的active方法
ctx.fireChannelActive();  // findContextInbound(MASK_CHANNEL_ACTIVE)


readIfIsAutoRead();
// 调用pipeline.read方法
2.3.4.1 readIfIsAutoRead从pipeline的尾结点开始读取
2.3.4.2 读取到headContext节点

调用headContext.read读取,即调用unsafe.beginRead(),这里的unsafe实现类是NioMessageUnsafe

2.3.4.3 doBeginRead

这里才真正将accept事件加入到selector感兴趣中

ini 复制代码
final int interestOps = selectionKey.interestOps();
if ((interestOps & readInterestOp) == 0) {
    selectionKey.interestOps(interestOps | readInterestOp);
}

3.初始化完成

至此,可以开始接收网络数据。

  1. 有连接过来,会在bossGroup线程中感知到,具体逻辑在NioEventLoop.run方法中可以查看。
  2. 具体处理读请求数据的在NioMessageUnsafe.read中
相关推荐
wuminyu3 小时前
专家视角看Java字节码加载与存储指令机制
java·linux·c语言·jvm·c++
callJJ4 小时前
Spring Data Redis 两种编程模型详解:同步 vs 响应式
java·spring boot·redis·python·spring
wbs_scy5 小时前
Linux线程同步与互斥(三):线程同步深度解析之POSIX 信号量与环形队列生产者消费者模型,从原理到源码彻底吃透
java·开发语言
jinanwuhuaguo6 小时前
(第三十三篇)五月的文明奠基:OpenClaw 2026.5.2版本的文明级解读
android·java·开发语言·人工智能·github·拓扑学·openclaw
xmjd msup7 小时前
spring security 超详细使用教程(接入springboot、前后端分离)
java·spring boot·spring
952367 小时前
SpringBoot统一功能处理
java·spring boot·后端
Lyyaoo.7 小时前
优惠券秒杀业务分析
java·开发语言
消失的旧时光-19437 小时前
统一并发模型:线程、Reactor、协程本质是一件事(从线程到协程 · 第6篇·终章)
java·python·算法
勿忘初心12217 小时前
Java 国密 SM4 加密工具类实战(Hutool + BouncyCastle)|企业级数据加密 + 兼容 JDK8
java·数据安全·数据加密·后端开发·企业级开发·国密 sm4
庞轩px7 小时前
第8篇:原子类与CAS底层原理——无锁并发的实现
java·cas·乐观锁·aba·无锁编程·自旋