☰
网关架构:小米小爱单机百万长连接网关架构
2026/10/20 11:25:41 网站建设 项目流程

小米小爱单机百万长连接网关架构

小爱接入层是小爱云端设备接入的核心服务。早期基于 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。

传输层支持三种通道:

  • ws:WebSocket over TCP;
  • wss:加密 WebSocket;
  • xmd:UDP 通道。

不同通道的差异通过 C++ 多态抽象为 Channel 接口,状态机主逻辑保持统一。

五、后端实现

后端使用 Scala 和 Akka Actor。最关键的改造是无状态化:所有与连接状态相关的信息都从后端移除,一次连接上的多个请求在后端被当作独立请求处理。

ZeroMQ

DispatcherActor

BIND 鉴权

LOGIN 登录

LOGOUT 登出

UPDATE / PING

TEXT / BINARY

RequestActor

业务 Actor

前后端使用 Protobuf 交互,减少 JSON 解析开销。BIND、LOGIN、LOGOUT、UPDATE、PING、TEXT_MESSAGE、BINARY_MESSAGE 分别处理设备鉴权、登录、登出、状态更新和消息转发。

六、容量优化

从 28 万提升到 120 万以上,关键优化有:

  • 前后端通信从 JSON 换成 Protobuf,CPU 占用明显下降;
  • 业务层 JSON 采用部分解析,只解析 header 获取namespace和name,CPU 下降 10%;
  • 心跳消息曾占收发消息总量的 75%,延长心跳时间有效降低 CPU;
  • 使用自研 Boost ASIO 异步多线程 TCP 通讯库,提升与后端服务通信性能。

七、未来规划

2.0 版计划进一步用 C++ 重写后端,将前端非必要功能继续后移,使前端更小更稳定。如果前端与后端处理能力差异较大,还可以用网络库替换 ZeroMQ,实现前后端从 1:1 部署变为 1:N 部署,目标单前端达到 200 万以上连接。

八、总结

小爱网关的实践说明:长连接容量优化不能只盯着协议库,还要从状态边界、进程拆分、序列化、心跳、线程模型和内存管理同时下手。有状态前端最小化,无状态后端最大化,是降低上线风险的关键。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询