由于业务需求, 需要实现实时获取服务端更新的数据功能, 基于这个需求, 进行调研及技术方案的实施, 最终决定采用 MQTT +ProtocolBuffer 基于长连接的数据实时推送的方案; 具体实现方案见本文;
本文包括三个部分: 1. 技术选型 2. 技术方案实践 3. 未来优化方向
技术选型
在调研过程中, 发现需求功能可以使用推送来实现, 但最终经过各种考虑, 发现自建长连接进行实时数据推送是最为贴合需求的实现方案; 调研过程中, 对推送厂家方案及本文方案做了对比, 结果如下:
推送 SDK | 集成 APNs | 保持长连接 |
---|---|---|
极光推送 | 是 | 是 |
个推 | 是 | 是 |
百度推送 | 是 | 否 |
腾讯信鸽 | 是 | 否 |
本文方案 | 否 | 是 |
从表格来看, 本文方案不过是极光推送和个推的一种简化版, 完全可以使用极光推送和个推来实现, 或者是使用推送来进行数据推送; 但从需求具体来讲, 才更能体现本文方案的可行性及必要性; 具体分析如下:
推送方案具有极大的不确定性, 消息丢失率比较高
极光推送和个推 SDK 采用了长连接的方式, 但是长连接协议并不可知, 且数据传输格式, 链接存在状态不受控制
自定方案, 因采用 MQTT 和 Protocol Buffer 两种协议, 对弱网情况兼容较好, 设备性能要求相对较低, 且对数据格式优化比较好, 且链接状态完全可控, 可以实时监控到链路是否可用, 对分析问题, 解决问题有很大便利;
技术方案实践
方案流程
整个技术方案大体流程如下图:
推送流程图. PNG
在整个过程中, 消息的实时传送靠推送后台和长连接 SDK 建立的长连接来实现; 而基于本方案实现的 SDK 则负责和推送后台维持长连接的有效性以及维持长连接的优化功能;
详细流程中涉及到的交互方和交互流程参照下图:
详细交互流程. PNG
方案架构
在整个数据实时传送方案中, 涉及到长连接的建立维护, 通信数据按协议封装, 业务数据封装及优化等功能, 在此对整个方案进行整理, 整理之后结构如下:
推送服务 SDK 层级. PNG
在整体结构中, 分为业务层, 应用层, 传输层, 和网络层, 其中业务层, 应用层, 传输层组成了数据实时推送服务的 SDK;
1. 业务层: 主要处理业务数据, 消息存储, 消息丢失, 重复处理, 以及数据格式转化等;
2. 应用层: 该层为整个 SDK 的核心层, 封装了 MQTT 协议, 以及对断线重连, 安全连接等;
3. 传输层: 该层主要核心为调用系统 API 实现长连接, 数据封包, 超时重发等处理;
下面对整个 SDK 架构层级, 以及各层级间包含的模块进行详细整理及说明; 如下图:
长连接方案结构图. PNG
业务层
该层主要解决, 数据格式转化, 消息丢失, 重复, 消息存储, 数据统计等功能; 下边对这些功能逐一介绍:
数据格式转化: 此模块负责将 ProtocolBuffer 类型的数据转化成 JSON 数据
消息重复, 丢失处理: 此模块会根据规则判断收到的消息是否重复, 或者在收到该信息之前是否丢过消息, 经过处理之后, 如果重复则不再传给业务方, 如果有消息丢失也将告诉业务方, 以便业务方处理相关情况;
消息存储: 根据一定缓存策略对消息进行短时间存储, 以便解决消息判重, 处理丢失等问题;
数据统计: 此模块将对消息进行统计, 区分重复, 丢失等情况, 并将数据上报服务器, 方便验证整个方案的可行性和问题等;
应用层
该层命名的来源主要来自于 MQTT, 因 MQTT 属于业务层协议, 该层的操作绝大部分是对协议的实现以及优化; 主要包含 MQTT 的实现, 心跳机制, 断线重连机制, 链接状态管理等;
MQTT 的实现: 此模块主要采用三方库 MQTTClient, 该三方库对 MQTT 协议进行了完整封装, 目前阶段, 该方案对 MQTT 协议的实现暂时依赖该库;
心跳机制: 因项目初期, 且方案有待验证, 此模块暂时使用较为简单的固定心跳机制, 设置心跳间隔为 60S; 对于该心跳间隔, 因不确定个运营商的 NAT 超时时间, 故对心跳间隔设置较小, 此间隔可能引起手机流量, 电量消耗的增加, 此模块为后续重点优化模块;
断线重连机制: 因存在网络切换, 移动网络基站变更, 以及网络断开等问题, 特提供断线重连机制, 此机制目前采用方案为: 以 2 的 n 次方为时间间隔进行重连, n 为重连次数, 当 n 等于 6 时不再重试;
链接状态管理: 此模块负责对应用前台, 后台不同状态情况下, 链接的处理情况的管理;
传输层
该层主要为调用系统 API 对 Socket 数据进行拼接组装, 以及发起连接, 关闭连接等操作;
对于该方案的具体模块, 以上均已介绍完毕, 以下是对该方案大致流程的梳理, 如下图:
数据处理流程. PNG
此流程展示出了 SDK 从建立链接, 接收数据, 经由 TCP 数据包处理, MQTT 通信数据解析, 到 ProtocolBuffer 数据格式处理等大致流程; 到此, 整个现有方案结束;
未来优化方向
考虑到移动端手机电量, 流量, 及网络连接不稳定的情况, 上述方案显然不是完美的方案, 针对上述方案, 现有以下规划:
智能心跳策略
因心跳是保证连接存活的必要手段, 心跳的存在毋庸置疑, 但是心跳的存在, 也必定会增加电量, 流量的消耗; 在此针对该方案的心跳策略提出以下针对性优化设想, 特提出以下方案 --- 智能心跳策略; 大致流程如下图:
智能心跳策略. PNG
断线重连机制优化
因有可能发生服务器异常, 造成客户端集体掉线的情况, 客户端会立刻发起重连, 在用户量较小的情况下, 客户端集体重连对于服务端可以承受, 但当用户量级达到一定数量, 大量客户端的重连, 可能就会产生重连风暴, 直接导致服务端再次出现异常, 因此对于重连机制也应考虑一个比较合适, 能避免重连风暴的策略;
网络连接优化
IP 直连, 链路复用, 控制传输包大小等,
来源: http://www.jianshu.com/p/7e97af44110e