第 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 — 客户端连接材料(练习进阶)