自动化 Socket 协议设计:消息序列、心跳、幂等重试与背压
摘要:TCP/WebSocket 能可靠传输字节或消息,不代表自动化任务只执行一次。断线重连、超时重试和慢设备会造成重复动作、消息堆积与失控。本文设计带版本、序号、幂等键、确认、心跳、租约和背压的应用层协议。
一、消息信封
json
{
"protocol": "autotest/2",
"message_id": "msg-0018",
"task_id": "task-demo-31",
"step_id": "launch",
"attempt": 1,
"type": "COMMAND",
"sent_at": "2026-07-14T08:00:00Z",
"payload": {"action": "app.launch"}
}
二、序号与确认
连接内序号用于检测缺口和重复;业务确认返回 message_id + execution_id + result。收到 ACK 只表示服务端接受还是执行完成,必须用不同状态明确表达。
三、幂等
服务端以 task_id + step_id 查执行记录。重复命令若已完成,返回原结果;若执行中,返回当前 execution_id;非幂等动作必须有唯一事务保护。
四、心跳
心跳证明通道活着,不证明应用 ready。分别维护:
- transport heartbeat;
- agent health;
- device health;
- task progress。
心跳携带随机 nonce 或序号,ACK 回显以测量 RTT 和识别旧包。
五、重连退避
异常断开后使用随机抖动和指数退避,避免大量客户端同时重连。RFC 6455 也建议异常关闭后延迟并逐步增加重试间隔。
六、背压
text
max_inflight_commands
max_queue_bytes
max_artifact_streams
high_watermark / low_watermark
达到高水位暂停普通任务,优先心跳、取消和错误消息。不能让大文件传输挤死控制通道。
七、控制与数据分离
命令/状态走控制通道,大型 Trace 和截帧走独立数据通道或对象存储;控制消息只引用 artifact_id、大小和哈希。
八、租约与脑裂
设备任务携带 lease_id 和 generation。旧连接恢复后若 generation 过期,所有写命令被拒绝,避免两个调度器同时控制设备。
九、错误模型
text
RETRYABLE_TRANSPORT
RETRYABLE_DEVICE_BUSY
PERMANENT_UNSUPPORTED
TASK_CANCELLED
LEASE_EXPIRED
DUPLICATE_COMPLETED
十、安全
使用认证与加密通道,限制消息大小和 JSON 深度,对 action 采用允许列表;日志屏蔽 Token、账号、设备 ID 和内部地址。
结语
可靠传输只是协议底座。自动化系统还需要应用级幂等、任务状态、心跳分层、租约和背压,才能在断线、慢设备和批量并发下保持可控。
参考资料:RFC 6455 WebSocket