主题
Netty 学习路线
适用版本:Netty 4.1.x(示例用 4.1.115.Final)。Netty 5 已放弃,不要按 5 的 API 写。
这套内容解决什么问题
写一个能跑的 TCP 服务不难,难的是它在长连接、半包、慢客户端、内存泄漏、断线重连下仍然稳定。Netty 把这些问题的通用解法封装成 EventLoop、Pipeline、ByteBuf 和编解码器;本目录按「线程模型 → 责任链 → 缓冲区 → 协议边界 → 生产故障」组织。
前置条件
- 知道 Java NIO 的 Channel/Selector/ByteBuffer;不熟先读 06-IO与NIO。
- 知道 TCP 是字节流、没有消息边界。
- 能读 Java 多线程与锁的基本代码。
环境自检(示例不依赖 Docker):
bash
java -version && mvn -v阅读顺序
| 顺序 | 篇目 | 解决的问题 | 读完的验收动作 |
|---|---|---|---|
| 1 | 01-核心架构与线程模型 | 谁在 accept、谁在读写、为什么无锁 | 跑通 echo server,说出 Boss/Worker 分工 |
| 2 | 02-ChannelPipeline与Handler | 事件怎么在 Handler 间传递 | 写出 inbound/outbound 各一个 Handler |
| 3 | 03-ByteBuf与零拷贝 | 缓冲区怎么读写、怎么少拷贝 | 用 slice/CompositeByteBuf 做一次零拷贝 |
| 4 | 04-拆包粘包与编解码 | 怎么从字节流切出完整消息 | 用 EmbeddedChannel 测半包/粘包 |
| 5 | 05-Netty生产踩坑 | 泄漏、心跳、重连、阻塞怎么排 | 复现一次泄漏并定位 |
怎么读
- 先读 01 并跑通示例;不跑代码,后面的 Pipeline 和 ByteBuf 会停留在概念。
- 03 与 04 可以对照读:ByteBuf 解决「怎么存」,FrameDecoder 解决「怎么切」。
- 05 是故障篇,建议在写完第一个长连接服务后再读,带着问题看。
- 每篇的「最小上手」都要能独立执行;缺依赖时先补依赖,不要跳过。
学完的验收
不看笔记,能完成下面四件事:
- 从零写一个 echo server,说明 Boss 和 Worker 各处理什么事件。
- 给 Pipeline 加一个 FrameDecoder 和 Encoder,解释
ctx.write与channel.write分别经过哪些 Handler。 - 用
EmbeddedChannel构造半包和粘包,证明业务 Handler 收到的是完整帧。 - 看到
OutOfDirectMemoryError时,说出先看哪两个指标、在哪个环境开PARANOID。
常见误区
- 以为「Boss 多配几个线程就能容错同一个端口」:监听 Channel 只绑一个 EventLoop。
- 以为「IdleStateHandler 会发心跳」:它只触发事件,心跳要自己写。
- 以为「Netty 的零拷贝等于 OS 零拷贝」:多数是用户态减少复制。
- 以为「池化一定更快」:要看分配大小和线程模型,不能套用固定百分比。
与相邻目录的关系
- NIO/Selector/零拷贝的系统知识在 06-IO与NIO。
- Reactor 模式在 Spring WebFlux/Gateway 中也有体现,可对照 05-服务网关。
- RPC 框架(Dubbo)的传输层通常就是 Netty,见 09-Dubbo核心原理。
版本与平台
| 项 | 4.1.x 的默认/事实 | 备注 |
|---|---|---|
| 默认分配器 | PooledByteBufAllocator | 可用 -Dio.netty.allocator.type=unpooled 关闭 |
| Worker 线程数 | CPU 核数 × 2 | NioEventLoopGroup 默认 |
| 传输 | NIO;Linux 可用 native epoll | 需引入 netty-transport-native-epoll |
| 泄漏检测 | SIMPLE | PARANOID 仅预发 |
生产执行项见 99-生产检查清单;正文讲机制,清单管动作,不逐条重复。