
小米小爱单机百万长连接网关架构小爱接入层是小爱云端设备接入的核心服务。早期基于 Akka 和 Play Framework 实现单实例长连接上限约 28 万经过前端 C、后端 Scala、ZeroMQ 通讯和协议优化后单机连接数提升到 120 万以上并节省了 30 多台机器。一、接入层职责小爱接入层主要承担三件事安全传输与鉴权维护设备长连接和心跳将设备请求转发到后端服务。小爱设备小爱接入层鉴权授权传输层请求转发小爱大脑二、早期架构的问题Akka Play 的版本能快速搭建并实现异步化但随着长连接数量增长问题逐渐暴露JVM GC 成为瓶颈单实例约 28 万连接Actor 之间存在大量状态依赖代码像函数调用而非不可变消息传递协议解析依赖较重升级会引发重连和雪崩风险Play 框架无法获取底层 TCP 连接数据长连接打点不准确。三、重构思路前后端拆分新版接入层按“是否有状态”拆成两个进程模块状态功能前端有状态连接保持、协议解析、加解密、顺序化后端无状态请求解析、业务分发、鉴权设备前端C 有状态ZeroMQ 通讯层后端Scala 无状态AIMS / XMQ前端保持设备连接后端无状态化后可以随时重启而不影响连接避免版本升级引发长连接重连。四、前端实现前端使用 C由四个子模块组成传输层WebSocket 解析、XMD 协议解析分发层把不同传输层事件转换成统一事件状态机层基于自研 XMFSM单线程 Actor 抽象ZeroMQ 通讯层用两个线程把阻塞接口异步化。自研 WebSocket 库基于 Boost ASIO 和 ASIO无锁设计。压测中 100 万长连接、5 万 QPS 下 P99 延迟为 5ms。传输层支持三种通道wsWebSocket over TCPwss加密 WebSocketxmdUDP 通道。不同通道的差异通过 C 多态抽象为 Channel 接口状态机主逻辑保持统一。五、后端实现后端使用 Scala 和 Akka Actor。最关键的改造是无状态化所有与连接状态相关的信息都从后端移除一次连接上的多个请求在后端被当作独立请求处理。ZeroMQDispatcherActorBIND 鉴权LOGIN 登录LOGOUT 登出UPDATE / PINGTEXT / BINARYRequestActor业务 Actor前后端使用 Protobuf 交互减少 JSON 解析开销。BIND、LOGIN、LOGOUT、UPDATE、PING、TEXT_MESSAGE、BINARY_MESSAGE 分别处理设备鉴权、登录、登出、状态更新和消息转发。六、容量优化从 28 万提升到 120 万以上关键优化有前后端通信从 JSON 换成 ProtobufCPU 占用明显下降业务层 JSON 采用部分解析只解析 header 获取namespace和nameCPU 下降 10%心跳消息曾占收发消息总量的 75%延长心跳时间有效降低 CPU使用自研 Boost ASIO 异步多线程 TCP 通讯库提升与后端服务通信性能。七、未来规划2.0 版计划进一步用 C 重写后端将前端非必要功能继续后移使前端更小更稳定。如果前端与后端处理能力差异较大还可以用网络库替换 ZeroMQ实现前后端从 1:1 部署变为 1:N 部署目标单前端达到 200 万以上连接。八、总结小爱网关的实践说明长连接容量优化不能只盯着协议库还要从状态边界、进程拆分、序列化、心跳、线程模型和内存管理同时下手。有状态前端最小化无状态后端最大化是降低上线风险的关键。