终点站做两场复盘。API 网关是把洋葱模型用到极致的形态——所有进层动作(鉴权、限流、路由、聚合)压缩在门口的几层里;中后台系统是洋葱模型的常规大赛——几十个资源、多角色权限、复杂业务规则。两场复盘都用同一套方法:先画层序图,再把全册知识点逐条对号入座。读完本节,你应该能把这套复盘方法用于任何 Koa 系统。
某内容平台的网关服务,前置在几十个业务微服务之前,日均请求过亿。它的层序图(真实项目的简化版):
const app = new Koa<GatewayState, GatewayContext>(); app.use(errorHandler()); // 1 兜底(2.4):最外层,含上游超时的降级响应 app.use(requestId()); // 2 请求 ID(6.2):全链路追踪的主键 app.use(accessLogger()); // 3 访问日志(3.3):含耗时分桶 app.use(httpMetrics()); // 4 指标采集(8.3):黄金信号 app.use(compress()); // 5 压缩(8.2):网关统一压,后端服务不重复压 app.use(ipRateLimit()); // 6 IP 限流(3.3):Redis 计数,挡最粗的滥用 app.use(authGateway()); // 7 统一鉴权(7.2):验 JWT,写 user 进 state app.use(userRateLimit()); // 8 用户级限流(3.3):登录后的精细配额 app.use(routeTable()); // 9 路由表:映射路径前缀到下游服务 app.use(proxyForward()); // 10 转发:透传 reqId 与 user 头(9.2 纪律一) app.listen(8080);
对照全册知识的四个落点。层序即架构(3.4):鉴权在路由前,未登录请求根本不进转发层——网关把"拦截靠外"做到了极致。限流两档(3.3):IP 档在鉴权前(不认识你也照挡),用户档在鉴权后(按身份精细配额),同一个限流工厂两种配置。错误降级(2.4):上游超时的响应在兜底层统一转为 504 加固定结构,后端服务挂掉对客户端表现为"可控的慢",而非"随机的错"。传递纪律(9.2):转发层透传 reqId 与解析后的用户头,下游服务信任网关注入的头、拒绝外来的同名头——信任边界在网关处收口。
某企业管理系统:几十个资源(客户、合同、审批流)、多角色权限、审计要求。它的目录与层设计:
src/ ├── app.ts 装配:层序唯一真相源 ├── middleware/ errorHandler · requestId · accessLogger │ auth(JWT) · rbac(角色) · validate · auditLog ├── domains/ │ ├── contract/ routes(路由级挂 rbac+validate) / service / repo │ ├── approval/ 审批流:状态机在 service 层 │ └── customer/ ├── shared/ HttpError 层次 · 校验器 · Redis 缓存封装 └── tests/ 单测(逐层) + 集成(supertest)
六个知识点的对号入座。权限两层拆(7.1):rbac 中间件管垂直权限(角色能不能调这个接口,挂在路由声明上),资源归属校验在 service 层管水平权限(这单合同是不是你的)——探测性访问统一回 404。审计是出层动作(3.3):auditLog 中间件在出层阶段记录"谁在什么时候对哪个资源做了写操作、结果状态码是什么",try/finally 保证失败的操作也留痕。状态机收口在 service(4.2):审批流的每一次状态迁移走显式动作方法,routes 层不允许触碰 status 字段——PATCH 只编辑属性,状态迁移走 /submission 这类动作子资源。缓存只放缓读(8.2):组织架构、数据字典进 Redis 加进程内 LRU;合同金额等强一致数据绝不缓存。测试金字塔(8.3):rbac 与 validate 中间件逐分支单测,每个业务域至少一条"创建、越权读、状态冲突"的集成链路。指标按域拆(8.3):错误率与 P99 按业务域打标签,审批流的慢与客户查询的慢分开告警。

两场复盘用的是同一套四步法,可以直接搬进团队。第一步画层序:把入口到出口的每一层写成一列,一层一行,禁止合并。第二步逐层问三问:进层做什么、出层做什么、截停条件是什么——答不出的层要么是冗余、要么是隐式行为。第三步对号全册清单:错误有没有统一出口(2.4)、reqId 有没有贯通(6.2)、权限有没有两层拆(7.1)、缓存有没有失效策略(8.2)、监控有没有按域拆(8.3)。第四步找隐性耦合:任何一层读了内层才产出的数据,就标记依赖方向,检查它是否真的该在那个位置。
💡 关键直觉:架构评审的胜负手不在新知识,在旧知识的落实率。网关与中后台没有用任何本册之外的技巧,它们只是把每一章的知识点逐条落了地——洋葱模型的价值最终体现在"每一层都答得出自己为什么在那里"。
全册至此收官。从第 1 章那颗二十行的最小洋葱,到网关与中后台的完整系统,"进一层、出一步"的主线贯穿始终——愿它也贯穿你此后的每一次服务端设计。