第 46 章 / 共 51 章
卷五 · 扩展、运维与实战
实战二:XTP2 TCP 网关(key-value 服务)
在 TCP 上说 XTP2:一个带会话、命令分发、服务端推送的 KV 网关——ch23 与 ch33 的全部概念在这里合体。
本章导读
站位二进制协议方向的毕业项目。协议选择 XTP2 而非自造帧格式,让你把精力放在服务结构上——这正是框架时代该有的分工。
46.1 项目目标
| 能力 | 设计 |
|---|---|
| 命令集 | GET/SET/DEL/PING(REQUEST → RESPONSE,id 关联) |
| 推送 | key 变更时向订阅连接发 EVENT(PUSH 通道) |
| 会话 | 连接注册表:处理器 + 残留缓冲 + 订阅集 |
| 持久 | 内存 KV + 可选落盘(复用 ch32 模式) |
| 防线 | xtp2 limits + idle_timeout + 命令限速 |
| 部署 | 明文 9000 + TLS 9443 双端点 |
46.2 会话与命令分发
分发核心(ch33 组装的延伸)
static void DispatchMessage(XS_StreamConn* pConn, const xtp2_message* pMsg)
{
switch ( pMsg->command ) {
case CMD_GET: {
xtp2_span tKey = { pMsg->body, pMsg->body_size };
xbuffer* pVal = KV_Get(tKey);
ReplyResponse(pConn, pMsg->id, pVal ? 0 : 1, pVal); /* id 回带 */
break; }
case CMD_SET:
KV_Set(SplitKeyVal(pMsg)); /* body = key\0val 约定 */
NotifySubscribers(SplitKey(pMsg), pMsg); /* EVENT 推送 */
ReplyResponse(pConn, pMsg->id, 0, NULL);
break;
default:
ReplyResponse(pConn, pMsg->id, 4096 + pMsg->command, NULL); /* 未知命令 */
}
}
/* ReplyResponse:measure→encode→Send(复用 ch33 的打包模式)*/
刚才发生了什么:命令字段(u16)成为稳定的分发轴——新增命令 = 加一个 case + 一条文档,协议表面(帧格式)完全不动。错误码空间也做了划分(0 成功 / 1 未找到 / 4096+ 协议层错)——实战一的"错误约定先行"在二进制世界同样成立。
46.3 响应与推送
- id 关联:RESPONSE 原样回带 REQUEST 的 id——客户端据此匹配异步请求(一个连接可并发多个在途请求)
- EVENT 推送:订阅集(每会话一个 key 前缀集)在 SET 提交后遍历推送——广播纪律照抄 ch22(锁内遍历、拷贝发送、失败容忍)
- 背压:订阅风暴的防线是应用层限频(每连接每秒最大 EVENT 数)+ 慢消费者降级——ch22 的策略层背压平移到 TCP
46.4 防线与双栈
- limits 收紧:KV 的 value 上限就是 max_body——按业务设(如 256KB),别用 1MiB 默认
- 坏帧即断 + 计数:SessionDrop 时递增恶意帧计数器进 /stats(ch43 的观测习惯)
- 空闲回收:idle_timeout 清僵尸连接;订阅集随 Close 终态清理
- 双栈:明文(内网调试)+ TLS(对外)共享同一套回调(ch23 练习三的产出)——SNI 证书按 ch12 配置
46.5 验收清单
| 维度 | 标准 |
|---|---|
| 功能 | 四命令 + 订阅推送全通;id 关联正确 |
| 协议韧性 | 分片/粘包/恶意帧三类测试通过(ch33 练习) |
| 并发 | 单连接 100 在途请求压测;多连接广播无串扰 |
| 生命周期 | 换代后订阅自动恢复(订阅集进 Swap 快照——值可交接的又一样本) |
| 部署 | 双端点 + 证书热替换演练 |
常见错误
推送没有限频
- 症状
- 热点 key 高频 SET 时,订阅连接的发送缓冲膨胀。
- 原因
- TCP 发送是异步缓冲——应用层不设 EVENT 限频与合并(如 50ms 窗口合并同类),慢消费者会拖垮内存。照抄 ch22 策略层背压。
订阅集不交接
- 症状
- 热重载后推送失灵。
- 原因
- 订阅集是"值"(key 前缀字符串)——按 ch28 判据应当交接(快照进 Swap);会话注册表本身不交接(连接归旧代),新连接重新订阅。
编程练习
基础完成网关
按 46.2-46.5 完成 KV 网关(客户端可用嵌套 TCC 写测试端)。
验收:五维清单全绿。
进阶协议客户端
写一个最小客户端模块(connect → encode 请求 → feed 响应 → id 匹配),供其他脚本复用。
验收:并发 100 在途请求零串扰。
挑战HTTP 桥
加 HTTP 服务把 REST 请求转成 XTP2 调用(网关反向)——两个 server 协作(ch11)。
验收:REST 语义完整映射到命令协议;桥接层无阻塞。
小结
| 要点 | 结论 |
|---|---|
| 结构 | 会话注册表 + 命令分发表 + id 关联 |
| 推送 | EVENT 通道复用 WS 广播纪律(限频/合并/降级) |
| 防线 | limits 按业务收紧 + 坏帧即断 + idle 回收 |
| 代际 | 订阅集交接(值);会话表不交接(连接归代) |
本章涉及的 API 参考
xrt 延伸阅读
- xrt · tcp — 客户端连接材料(练习进阶)