《Java 服务端通信工程》目录与学习路径

《Java 服务端通信工程》全书导航:给出把 RPC 用对、把治理做起来、把系统跑稳三条学习路径,列出十五章四十五节的入口、每章验收动作与通过判据、linkd-v3 四模块的推进状态、章节依赖、跳读后果和附录用法,方便按目标定位或按依赖跳读。

全书结构

这一页是《Java 服务端通信工程》的总入口。它不只列标题,还给出三条可以照着走的路径、每章的验收信号,以及 linkd-v3 四个模块在什么阶段长出什么能力。

全书 50 篇,构成为:

部分篇数内容
前置3序 、前言 、目录
正文4515 章,每章 3 节
附录2通信 API 速查 、诊断与压测命令

正文十五章按能力分成五组:契约与调用(1–3)、传输与连接(4–6)、治理与入口(7–9)、安全与观测(10–12)、演练与收口(13–15)。分组不是按知识点分类,而是按「你现在能跑通什么」划分。每组的最后一章都留下一个可验证的能力,下一组在它上面继续。

linkd-v3 的模块状态

linkd-v3 是四模块工程,groupId com.plume.linkd.v3。能力随章节推进逐块长出来:

模块职责关键类型首次出现完成标志
comm-api.proto、stub、错误码LibraryGrpc、Book、RpcError第 1.3 节搭骨架9093 能编译出四个方法
comm-core发现、负载均衡、重试、熔断、限流、指标、追踪StaticRegistry、LibraryClient、RetryPolicy、TokenBucket第 3.3 节客户端能带预算调用下游
comm-server服务实现、拦截器、健康检查、反射LibraryService、RequestContextInterceptor第 3.1 节四个方法都能被调用
comm-gatewayHTTP/BFF、协议转换、下游调用BookHandler、ErrorMapper第 9.1 节9094 能用 HTTP 访问 9093

模块之间单向依赖:comm-gateway、comm-server 依赖 comm-core,comm-core 依赖 comm-api。正文不会中途改模块划分;需要新类时,只往对应模块里加。

用一段代码确认依赖方向没有被写反:

package com.plume.linkd.v3.demo;

import java.util.List;
import java.util.Map;

public final class ModuleGraph {

    private static final List<String> MODULES =
            List.of("comm-api", "comm-core", "comm-server", "comm-gateway");

    private static final Map<String, List<String>> DEPENDS_ON = Map.of(
            "comm-api", List.of(),
            "comm-core", List.of("comm-api"),
            "comm-server", List.of("comm-core"),
            "comm-gateway", List.of("comm-core"));

    public static void main(String[] args) {
        for (String module : MODULES) {
            List<String> deps = DEPENDS_ON.get(module);
            System.out.println(module + " -> " + (deps.isEmpty() ? "none" : String.join(",", deps)));
        }
        boolean apiDependsOnBusiness = DEPENDS_ON.get("comm-api").stream()
                .anyMatch(dep -> dep.startsWith("comm-"));
        System.out.println("direction.ok=" + !apiDependsOnBusiness);
    }
}

预期输出:

comm-api -> none
comm-core -> comm-api
comm-server -> comm-core
comm-gateway -> comm-core
direction.ok=true

依赖方向一旦反过来,comm-api 就会拖进服务实现,客户端为了拿一个 .proto 生成类不得不引入整个服务端依赖。这种错误在单模块里看不出来,拆成多模块后才暴露。

三条学习路径

三条路径的入口相同,目标不同。选一条为主,其他章节按需补,不要三条同时推进。

路径一:把 RPC 用对(约 3 周)

适合第一次把 HTTP 调用换成 gRPC、或者要设计一套内部接口的人。主线是「契约先定,错误和时间先说清」。

周章节目标
1第 1 章能写出带错误码和兼容规则的 .proto
2第 2 章能解释一个字段在线上的字节,知道哪些改动不兼容
3第 3 章 + 4.1 Stub 与 Channel 生命周期能设置 deadline、取消、幂等键和重试

验收信号:给出一个 GetBook 请求,能写出它的字节序列、失败时的状态码与原因码,以及“重试两次是否安全”的判断。

路径二:把治理做起来(约 5 周)

适合正在维护多服务调用、需要处理超时、重试、熔断和限流的人。主线是「故障在到达核心逻辑之前被吸收」。

周章节目标
13.2 Deadline 传播与取消能画出一次调用的时间预算
2第 5 章能注册服务、解析地址、选择负载均衡策略
3第 6 章能解释连接复用、连接池与 drain
4第 7 章能实现重试预算、熔断状态机和 Bulkhead
5第 8–9 章能做限流、背压和网关错误映射

验收信号:下游延迟升高时,调用方的重试不会放大流量;熔断打开后请求快速失败;网关返回的错误能对应到明确的原因码。

路径三:把系统跑稳(约 6 周)

适合负责上线、值班、容量和故障复盘的人。主线是「先看得见,再改得动,最后能验收」。

周章节目标
111.1 指标口径与 Prometheus 文本能定义请求量、错误率、延迟直方图
211.2 结构化日志与 traceparent能用请求 ID 串起客户端与服务端
3第 12 章能做版本兼容、灰度路由和契约测试
4第 13 章能设计故障注入与演练
5第 14 章能建容量模型、设计压测、给出成本口径
6第 15 章能按验收清单完成 linkd-v3 接入

验收信号:一次故障能定位到具体请求、具体下游、具体版本;灰度可以按比例切流并回滚;容量结论有机器口径和指标,不靠单次 QPS。

十五章与四十五节

下表每一行是一章,三个链接分别是该章的三节。首节建立概念边界,后两节负责落地;时间有限时,至少读首节和该章最后一节的「常见错误」。

章主题三节入口读完能做什么
1通信协议设计方法论1.1 从 RPC 语义到线格式 · 1.2 错误模型与状态码 · 1.3 契约先行与演进边界说清一次调用在线上的形状,写出可演进的契约
2序列化、IDL 与兼容性2.1 Protobuf 编码与 schema · 2.2 JSON 与 Protobuf 的取舍 · 2.3 字段演进与兼容矩阵能手算字段编码,判断一次改动是否兼容
3RPC 调用模型与超时语义3.1 四种调用模式 · 3.2 Deadline 传播与取消 · 3.3 幂等、重试与请求去重能选对调用模式,能算预算,能安全重试
4gRPC-Java 深入4.1 Stub 与 Channel 生命周期 · 4.2 Interceptor 与 Metadata · 4.3 Codec、压缩与消息上限能管理 Channel、写拦截器、控制消息大小
5服务发现与负载均衡5.1 注册中心模型 · 5.2 自定义 NameResolver · 5.3 round_robin、pick_first 与健康检查能让客户端找到并分散到多个实例
6连接复用与连接池6.1 HTTP/2 多路复用与连接数 · 6.2 客户端连接池设计 · 6.3 连接生命周期与 drain能解释连接数、流数、drain 的关系
7重试、熔断与隔离7.1 重试预算与退避 · 7.2 熔断状态机 · 7.3 Bulkhead 与线程隔离能让故障快速失败,不拖垮调用方
8限流、背压与队列8.1 令牌桶与漏桶 · 8.2 服务端并发限制 · 8.3 队列与背压能控制入口速率,能处理慢消费者
9网关、协议转换与 BFF9.1 HTTP 到 gRPC 的网关 · 9.2 BFF 聚合与裁剪 · 9.3 错误与超时映射能把 HTTP 稳定地转到 gRPC,并映射错误
10认证、授权与传输安全10.1 TLS 与 mTLS · 10.2 Token 传播与校验 · 10.3 授权模型与租户隔离能加密传输、传播身份、隔离租户
11可观测性11.1 指标口径与 Prometheus 文本 · 11.2 结构化日志与 traceparent · 11.3 追踪、采样与 exemplar能用指标、日志、追踪定位一次慢调用
12版本演进与灰度兼容12.1 API 版本策略 · 12.2 灰度路由与流量切分 · 12.3 契约测试与回滚能发布新版本并安全回滚
13混沌演练与故障注入13.1 故障模型与爆炸半径 · 13.2 注入实现与开关 · 13.3 演练设计与复盘能在受控范围验证故障路径
14容量规划与成本14.1 容量模型与 Little’s law · 14.2 压测剖面与瓶颈定位 · 14.3 成本、扩缩容与预算能算容量、做压测、给成本结论
15linkd 接入 libraryd(v3 验收)15.1 链路架构与边界 · 15.2 联调、验收清单与故障注入 · 15.3 运行手册与复盘能把四模块跑成一条可验收的链路

用一段代码确认目录没有被写错:十五章、每章三节,总数必须是 45。

package com.plume.linkd.v3.demo;

import java.util.List;

public final class StudyPlan {

    public record Chapter(int number, String title, int sections) {
    }

    public static void main(String[] args) {
        List<Chapter> chapters = List.of(
                new Chapter(1, "通信协议设计方法论", 3),
                new Chapter(2, "序列化、IDL 与兼容性", 3),
                new Chapter(3, "RPC 调用模型与超时语义", 3),
                new Chapter(4, "gRPC-Java 深入", 3),
                new Chapter(5, "服务发现与负载均衡", 3),
                new Chapter(6, "连接复用与连接池", 3),
                new Chapter(7, "重试、熔断与隔离", 3),
                new Chapter(8, "限流、背压与队列", 3),
                new Chapter(9, "网关、协议转换与 BFF", 3),
                new Chapter(10, "认证、授权与传输安全", 3),
                new Chapter(11, "可观测性", 3),
                new Chapter(12, "版本演进与灰度兼容", 3),
                new Chapter(13, "混沌演练与故障注入", 3),
                new Chapter(14, "容量规划与成本", 3),
                new Chapter(15, "linkd 接入 libraryd", 3));
        int sections = chapters.stream().mapToInt(Chapter::sections).sum();
        System.out.println("chapters=" + chapters.size() + " sections=" + sections);
        System.out.println("plan.ok=" + (chapters.size() == 15 && sections == 45));
    }
}

预期输出:

chapters=15 sections=45
plan.ok=true

章节依赖关系

下面这张图不是「必须按顺序读」,而是「跳过前置会缺什么」:

第 1 章 契约与错误模型
   └─ 第 2 章 编码与兼容性
        └─ 第 3 章 调用模型、Deadline、幂等
             ├─ 第 4 章 gRPC-Java 深入
             │    └─ 第 5 章 服务发现与负载均衡
             │         └─ 第 6 章 连接复用与连接池
             ├─ 第 7 章 重试、熔断与隔离
             │    └─ 第 8 章 限流、背压与队列
             │         └─ 第 9 章 网关与协议转换
             ├─ 第 10 章 认证、授权与传输安全
             ├─ 第 11 章 可观测性
             └─ 第 12 章 版本演进与灰度
                  └─ 第 13 章 混沌演练
                       └─ 第 14 章 容量与成本
                            └─ 第 15 章 验收与运行手册

几个具体的跳读后果:

  • 跳过第 1.2 节直接读第 7.2 节,熔断器只能按 HTTP 状态码判断失败,无法区分「业务不存在」和「下游不可用」。
  • 跳过第 3.2 节直接读第 7.1 节,重试预算没有时间基准,退避参数只能拍脑袋。
  • 跳过第 5 章直接读第 6 章,连接池不知道地址从哪来,只能把 host 写死。
  • 跳过第 11 章直接做第 14 章压测,只能看到 QPS,看不到尾延迟和错误分布。

跳章可以,跳依赖不行。

每章验收信号

不必等到第 15 章才验收。每读完一章,用下面的信号确认自己没有「看懂了但跑不通」:

章验收动作通过判据
1写一个 GetBook 的成功与失败响应失败响应带 reason 和 retryable,不是一段字符串
2手算 Book{isbn="42", stock=7} 的字节与 toByteArray() 的前缀一致
3给一次调用设置 800 ms 总预算单跳 300 ms,重试仍落在总预算内
4关闭并重建 ManagedChannel旧 Channel 的调用失败,新 Channel 正常
5注册两个实例并解析请求分散到两个地址,不是只打第一个
6观察一条连接上的并发流并发调用没有按连接串行
7让下游持续失败熔断打开后快速失败,半开只放少量探针
8超过 200 rps 持续打超出部分返回 RESOURCE_EXHAUSTED,服务不崩
9用 HTTP 调 9094正确转换到 9093,错误码映射到 HTTP 状态
10用错误 token 调用返回 PERMISSION_DENIED,不泄露内部信息
11查一次慢请求能从指标、日志、traceparent 三处对上同一个请求
12发布一个新增字段的版本旧客户端不失败,回滚不需要改数据
13注入 300 ms 延迟调用方在预算内失败,不产生重试风暴
14按固定剖面压测给出吞吐、p50/p99、错误率和机器口径
15按 15.2 清单逐项执行四个方法、网关、健康检查、关闭全部通过

自测记录至少包含日期、机器口径、命令、输出和结论。没有记录的结果,过一周就不可信。

附录与速查

篇目内容什么时候用
附录 A 通信 API 速查gRPC、Protobuf、Metadata、Status 的常用类与方法写代码时查签名
附录 B 诊断与压测命令lsof、netstat、tcpdump、JFR、压测参数排查连接、延迟、容量问题时

附录不是正文的替代。正文讲「为什么这样写」,附录讲「命令和签名是什么」。

小结

  • 全书 50 篇:前置 3 篇、正文 15 章 45 节、附录 2 篇。
  • 五组按能力递进:契约与调用、传输与连接、治理与入口、安全与观测、演练与收口。
  • 三条路径:把 RPC 用对约 3 周、把治理做起来约 5 周、把系统跑稳约 6 周。
  • linkd-v3 四模块单向依赖,comm-api 不依赖任何业务模块。
  • 每章都有验收信号;跳章可以,跳依赖不行。
  • 目录里的 45 个链接与正文一一对应,不虚增篇数,也不留占位标题。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「books」更多文章

  1. 《Java 消息中间件·事件驱动架构》附录 B 架构决策记录模板
  2. 《Java 消息中间件·事件驱动架构》附录 A 术语表
  3. 《Java 消息中间件·事件驱动架构》15.3 全书验收