全书结构
这一页是《Netty 高性能网络编程》的总入口。它不只列标题,还给出三条可以照着走的路径、每章的验收信号,以及 linkd-v2 四个模块在什么阶段长出什么能力。
全书 50 篇,构成为:
| 部分 | 篇数 | 内容 |
|---|---|---|
| 前置 | 3 | 序 、前言 、目录 |
| 正文 | 45 | 15 章,每章 3 节 |
| 附录 | 2 | API 速查、诊断与调优命令 |
正文十五章按依赖分成五组:地基(1–3)、数据通道(4–6)、协议与连接(7–9)、应用协议(10–12)、生产收口(13–15)。这个分组不是按知识点分类,而是按「你现在能跑通什么」划分。每组的最后一章都会留下一个可验证的能力,下一组在它上面继续。
这一页有三种用法:
- 刚拿到书。 先读「三条学习路径」,选一条,再用「十五章分组」确认入口章节。
- 读到一半。 用「每章首节入口」定位,表格里有一句话说明和验收信号,避免点进去再退出来。
- 当手册查。 直接看「每章首节入口」和附录,按关键词跳;每节末尾有小结和前后导航,跳读不会迷路。
linkd-v2 的模块状态
linkd-v2 是一个四模块工程,groupId com.plume.linkd.v2,版本 0.2.0-SNAPSHOT。它的能力不是一次写完的,而是随章节推进逐块长出来:
| 模块 | 职责 | 关键类型 | 首次出现 | 完成标志 |
|---|---|---|---|---|
linkd-core | 协议帧、编解码、共享常量 | LinkdFrame、FrameType、ProtocolConstants、LinkdFrameDecoder、LinkdFrameEncoder | 第 1.3 节搭骨架,第 7.1 节定型 | 9093 上的帧能被正确拆开与拼回 |
linkd-server | HTTP、WebSocket、HTTP/2、网关 | LinkdHttpHandler、WebSocketHub、GatewayHandler、ConnectionRegistry | 第 2 章起服务 | 9090/9091/9092 三套协议并存 |
linkd-client | 客户端、重连、连接池 | RpcClient、ReconnectHandler | 第 8 章 | 断线能重连,连接能借还 |
linkd-app | main、配置、生命周期 | LinkdV2Main | 第 1.3 节 | SIGINT 后能优雅关闭 |
模块之间不循环依赖:linkd-app 依赖另外三个模块,linkd-server 与 linkd-client 依赖 linkd-core。正文不会在中途改模块划分;如果某一节需要新类,只会往对应模块里加。
按章节看,模块状态大致这样推进:
| 阶段 | 涉及章节 | 已经能做什么 | 怎么确认 |
|---|---|---|---|
| 骨架 | 1–2 | 9090 启动,/healthz 返回 ok | curl 与 lsof |
| 数据通道 | 3–6 | Echo、帧解码、半包/粘包处理 | 单测 + Python 客户端 |
| 有状态协议 | 7–8 | 9093 的 HELLO/PING/REQUEST,客户端重连与池化 | 协议脚本 + 关闭测试 |
| 背压与多协议 | 9–11 | 水位控制、WebSocket、h2c、gRPC | 慢客户端 + 三种客户端 |
| 生产收口 | 12–15 | kqueue、泄漏检测、压测、网关 | 15.3 验收清单 |
「状态」是本书的推进顺序,不是对某个现成仓库的描述。你从第 1 章开始搭,走到第 15 章时,表格里的能力应该都能在自己的机器上复现。
三条学习路径
三条路径的入口相同,目标不同。选一条为主,其他章节按需补,不要三条同时推进。
路径一:协议实现线(约 6–7 周)
适合要写自定义协议、长连接客户端或服务端的人。主线是「一条帧从字节到业务对象,再回到字节」。
| 周 | 章节 | 目标 |
|---|---|---|
| 1 | 第 1–2 章 | 搭好四模块工程,9090 能启动并响应 /healthz |
| 2 | 第 3 章 | 理解 EventLoop 的线程归属,能解释为什么 handler 不能阻塞 |
| 3 | 第 4–5 章 | 能把 handler 挂进 Pipeline,能说清 ByteBuf 的读写索引与引用计数 |
| 4 | 第 6 章 | 用 ByteToMessageDecoder 处理半包、粘包和多帧 |
| 5 | 第 7 章 | 在 9093 上实现 HELLO/HELLO_ACK、PING/PONG |
| 6 | 第 8 章 | 客户端重连、连接池、关闭与半关闭 |
| 7 | 复习 + 自测 | 用独立客户端跑完握手、心跳、一次请求响应 |
这条路径的验收信号:
- 第 3 章结束:能画出「一个
Channel绑定一个EventLoop」的图,并能指出跨线程写为什么要execute。 - 第 6 章结束:解码器对「半帧」「两帧粘在一起」「超长帧」三种输入都有明确结果,不靠
Thread.sleep等数据。 - 第 7 章结束:9093 上
PING能收到PONG,HELLO能收到HELLO_ACK,错误帧返回ERROR。 - 第 8 章结束:杀掉服务端后客户端能重连;连接池借出的连接在异常路径上也能归还。
如果你只做协议,不做网关,第 9–15 章可以只读每章首节和小结。但第 9 章的背压和第 13 章的泄漏检测建议补上,否则长连接跑久了会遇到内存问题。
路径二:性能排查线(约 5–6 周)
适合正在维护 Netty 服务、需要从现象定位根因的人。主线是「先观测,再判断,最后才调参」。
| 周 | 章节 | 目标 |
|---|---|---|
| 1 | 第 2–3 章 | 能启动服务,能确认 EventLoop 的线程数与归属 |
| 2 | 第 4–5 章 | 能读懂 Pipeline 顺序与 ByteBuf 的生命周期 |
| 3 | 第 9 章 | 能用水位线和 Channel.isWritable() 判断写积压 |
| 4 | 第 12 章 | 能按平台选择 NIO/kqueue/epoll,并解释回退条件 |
| 5 | 第 13 章 | 能开 ADVANCED 泄漏检测,能读线程栈和连接状态 |
| 6 | 第 14 章 | 能设计一轮压测,给出指标口径与回归结论 |
这条路径不要求你先写完整个 linkd-v2,但要求你有一个能复现问题的服务。第 13 章的现象——LEAK:、堆外内存上涨、连接数不降、EventLoop 卡住——需要真实流量或可复现脚本才能验证。
验收信号:
- 能区分「CPU 高」「QPS 上不去」「延迟抖动」「内存上涨」四类现象,并说出各自先查什么。
- 能解释
ResourceLeakDetector的SIMPLE、ADVANCED、PARANOID各自适合什么场景。 - 能按第 14 章的口径记录吞吐、p50/p99、GC、RSS,不用单个 QPS 下结论。
- 能在 macOS 上正确使用 kqueue,不把
Epoll.isAvailable() == false当成 bug。
路径三:生产网关线(约 6–8 周)
适合要做接入层、API 网关或长连接入口的人。主线是「外部协议进来,经过路由、限流、超时、降级,转发到上游」。
| 周 | 章节 | 目标 |
|---|---|---|
| 1 | 第 1–2 章 | 工程骨架与 9090 服务 |
| 2 | 第 4 章 | Pipeline 顺序、异常传播、handler 状态 |
| 3 | 第 8 章 | 上游连接池、重连、关闭语义 |
| 4 | 第 9 章 | 网关侧的读写背压与水印 |
| 5 | 第 10 章 | WebSocket 会话表、心跳与广播 |
| 6 | 第 11 章 | h2c 与 gRPC 的边界,不把两者混为一谈 |
| 7–8 | 第 15 章 | 路由、限流、超时、降级、SIGINT 验收 |
这条路径的验收信号:
- 9090 的
/books/{id}能代理到127.0.0.1:8080,上游不可达时返回502并说明是代理失败。 /ws/echo回显文本帧,/ws/broadcast能把消息发给所有连接;断开的连接从会话表移除。- 9091 的 h2c 只做明文 prior-knowledge;TLS/ALPN 只说明边界,不在本卷实现。
- 超时、限流、降级各有明确触发条件和返回,不靠「多试几次」。
- 收到
SIGINT后停止接收新连接,在期限内关闭EventLoopGroup。
怎么选路径
如果不确定,按目标选,不要按章节难度选。难度高的章节不一定是当前需要的,先跑通目标链路更重要。
| 你的目标 | 选这条路径 | 建议先补 | 可以后置 |
|---|---|---|---|
| 写一个自定义协议的客户端/服务端 | 协议实现线 | 第 5、6 章 | 第 10–12 章 |
| 排查线上连接数、内存、延迟问题 | 性能排查线 | 第 9、13 章 | 第 7、10、11 章 |
| 做统一入口、代理、限流 | 生产网关线 | 第 8、9、15 章 | 第 6 章的细节 |
| 只想先跑一个 Echo 服务 | 第 1–3 章 | 第 2 章 | 其余全部 |
| 准备面试或系统复习 | 按十五章顺序 | 无 | 附录按需 |
选定路径后,不要因为某一章「看起来更重要」就临时插队。路径的顺序是按依赖排的,插队会把后面的验收信号打乱。
十五章分组
| 组 | 章 | 主题 | 读完能做什么 |
|---|---|---|---|
| 一、地基 | 1–3 | 架构定位、Bootstrap、EventLoop | 在 9090 启动一个可观测的 Echo 服务 |
| 二、数据通道 | 4–6 | Pipeline、ByteBuf、编解码器 | 正确拆帧、拼帧,处理半包与粘包 |
| 三、协议与连接 | 7–9 | 自定义协议、心跳、连接池、背压 | 9093 上有状态、有背压的长连接 |
| 四、应用协议 | 10–12 | WebSocket、HTTP/2、gRPC、原生传输 | 9090/9091/9092 三套协议并存 |
| 五、生产收口 | 13–15 | 泄漏检测、压测调优、网关验收 | linkd-v2 通过 15.3 的清单 |
每章首节入口
下表每一行都链到该章第一节。首节负责建立概念边界,后两节负责落地;时间有限时,至少读首节和该章最后一节的「常见错误」。
| 章 | 首节入口 | 解决的问题 | 验收信号 |
|---|---|---|---|
| 1 | 1.1 Netty 在网络栈中的位置 | Netty 管哪一层,不管哪一层 | 能画出应用、Netty、JDK、内核的边界 |
| 2 | 2.1 ServerBootstrap 与 Bootstrap | 服务端与客户端怎么启动 | 9090 能监听并接受连接 |
| 3 | 3.1 EventLoopGroup 与线程归属 | 线程数、绑定关系、任务队列 | 能解释一个 Channel 为什么只属于一个 EventLoop |
| 4 | 4.1 Pipeline 结构与事件传播 | 入站/出站方向与 handler 顺序 | 能预测一个事件经过哪些 handler |
| 5 | 5.1 ByteBuf 索引与视图 | 读写索引、切片、引用计数 | 能说清一块 ByteBuf 何时被回收 |
| 6 | 6.1 ByteToMessageDecoder | 半包、粘包与累积缓冲 | 解码器对三种输入都有确定结果 |
| 7 | 7.1 协议帧设计与魔数 | 16 字节头、魔数、长度上限 | 9093 能识别合法帧并拒绝非法帧 |
| 8 | 8.1 客户端连接与重连 | 建连、退避、重连边界 | 杀掉服务端后客户端能恢复 |
| 9 | 9.1 Channel.isWritable 与高低水位 | 写缓冲与背压信号 | 慢客户端下能观察到不可写与恢复 |
| 10 | 10.1 WebSocketServerProtocolHandler | 握手、帧、会话 | /ws/echo 能回显文本帧 |
| 11 | 11.1 Http2FrameCodec 与多路复用 | 连接级帧与流级 channel | 9091 能完成 h2c prior-knowledge |
| 12 | 12.1 原生传输与平台差异 | epoll/kqueue/NIO 的选择 | macOS 用 kqueue,缺失时回退 NIO |
| 13 | 13.1 ResourceLeakDetector | 泄漏级别与日志 | 能在 ADVANCED 下定位未释放的 ByteBuf |
| 14 | 14.1 参数基线:水位、缓冲区、线程数 | 参数与指标口径 | 能设计一轮可复现的压测 |
| 15 | 15.1 网关路由与转发 | 路由、代理、超时、降级 | /books/{id} 能代理并正确处理 502 |
章节依赖关系
第 1 章 架构定位
└─ 第 2 章 Bootstrap
└─ 第 3 章 EventLoop
├─ 第 4 章 Pipeline
│ └─ 第 5 章 ByteBuf
│ └─ 第 6 章 编解码器
│ └─ 第 7 章 自定义协议
│ └─ 第 8 章 连接与池化
│ └─ 第 9 章 背压
├─ 第 10 章 WebSocket
├─ 第 11 章 HTTP/2 与 gRPC
└─ 第 12 章 原生传输
└─ 第 13 章 泄漏与诊断
└─ 第 14 章 压测与调优
└─ 第 15 章 网关与验收
这个图不是「必须按顺序读」,而是「跳过前置会缺什么」。例如:
- 跳过第 5 章直接读第 9 章,会看不懂「写缓冲里的
ByteBuf谁释放」。 - 跳过第 6 章直接读第 7 章,会把「帧解码」写成「一次
read就有一条消息」。 - 跳过第 8 章直接读第 15 章,网关的上游连接池会没有借还语义。
- 跳过第 13 章直接做第 14 章的压测,内存上涨时无法判断是泄漏还是缓存。
跳章可以,跳依赖不行。三条路径已经按依赖排过序,照路径走不会踩这个问题。
每章之后的自测
不必等到 15.3 才验收。每读完一组,用下面的检查点确认自己没有「看懂了但跑不通」:
| 检查点 | 命令或动作 | 通过判据 |
|---|---|---|
| 第 2 章后 | curl -s http://127.0.0.1:9090/healthz | 返回 ok,状态码 200 |
| 第 6 章后 | 跑解码器单测,输入半帧、双帧、超长帧 | 三种输入分别得到「等待」「两帧」「拒绝」 |
| 第 7 章后 | 用 9093 客户端发 PING | 收到 PONG,requestId 对得上 |
| 第 9 章后 | 慢客户端只连不读,持续写入 | Channel.isWritable() 变 false,停止读;读走后恢复 |
| 第 11 章后 | curl --http2-prior-knowledge http://127.0.0.1:9091/healthz | 返回 200,不是 HTTP/1.1 降级 |
| 第 13 章后 | ADVANCED 级别跑一轮典型流量 | 无 LEAK:,或能定位到具体 handler |
| 第 15 章后 | 按 15.3 清单逐项执行 | HTTP、WS、h2c、gRPC、9093、关闭全部通过 |
自测记录建议包含:日期、机器口径、命令、输出、结论。没有记录的结果,过一周就不可信了。
附录与速查
| 篇目 | 内容 | 什么时候用 |
|---|---|---|
| 附录 A Netty 常用 API 速查 | Bootstrap、Channel、Pipeline、ByteBuf、codec 的常用方法与包名 | 写代码时查签名,替代搜索引擎 |
| 附录 B Netty 诊断与调优命令 | lsof、netstat、tcpdump、JFR、泄漏检测参数 | 排查连接、内存、线程问题时 |
附录不是正文的替代。正文讲「为什么这样写」,附录讲「命令和签名是什么」;两者配合使用。
常见问题
「一定要先读卷一吗?」 不强制,但建议至少读卷一的第 6、7 章(Reactor 与非阻塞读写)和第 8 章(HTTP/1.1)。没有这些,第 3、4、10 章的很多「为什么不能这样写」会缺少参照。
「可以跳过第 5 章 ByteBuf 吗?」 不建议。第 6 章的编解码器、第 9 章的背压、第 13 章的泄漏检测都依赖引用计数和读写索引。跳过它,后面只能靠背 API。
「为什么第 12 章在 macOS 上只讲 kqueue?」 因为 macOS 没有 epoll,Epoll.isAvailable() 返回 false 是正常现象。第 12.3 节讲 Linux 的 epoll 配置,但那是部署侧内容,不是本机实测。
「50 篇要读多久?」 按三条路径,大约 5–8 周;每周投入 8–10 小时。只读首节和小结可以压缩到 2–3 周,但代码跑不通,验收会露馅。
「15.3 验收前要准备什么?」 一个能启动的 linkd-v2、一个可用的 libraryd(8080)、三个客户端脚本(HTTP、WebSocket、9093 自定义协议),以及一份记录模板。清单本身在 15.3。
小结
- 全书 50 篇:前置 3 篇、正文 15 章 45 节、附录 2 篇。
- 五组按能力递进:地基、数据通道、协议与连接、应用协议、生产收口。
- 三条路径:协议实现线 6–7 周、性能排查线 5–6 周、生产网关线 6–8 周。
linkd-v2四模块从第 1 章搭骨架,第 7 章定型协议,第 8 章补客户端,第 15 章验收。- 每章首节建立边界,后两节落地;跳章可以,跳依赖不行。
- 每章都有自测信号,不必等到 15.3 才知道自己有没有跑通。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。