移动推送平台提供统一的服务,对于应用层屏蔽推送服务接口,且实现推送服务可动态轮替。推送平台将接收到的消息持久化到数据库中,方便进行消息推送失败后的重发,以及后续数据的统计分析。 客户端 SDK 对 App 提供统一的使用接口,屏蔽推送服务 SDK 使用细节,且实现多种推送 SDK 可替换,隐藏 SDK 复杂的接入过程,方便使用。 应用管理系统面向 App 开发人员,实现应用申请,推送服务配置,消息查询与管理,数据统计与分析。 主要流程 消息推送涉及的主要模块是消息推送平台和客户端 SDK,主要流程如下图所示:
图 3:消息推送中间件核心流程 正常情况下,消息推送过程如下: 系统接收到业务方的推送请求后,首先进行权限的验证,直播,这包括应用 appKey 的验证、接口参数的验证、黑名单验证等。 验证不通过,返回错误信息;验证通过后,为此条消息分配一个唯一 id(uuid),将消息内容持久化到数据库中,此时消息的状态为待发送。 消息进入推送队列中,将之后推送接口请求的响应返回给业务方。 推送队列的消费者从队列中取出待发送的消息,标记该条消息的状态为发送中,然后调用第三方推送服务接口进行发送。 如果调用成功,那么标记该消息的状态为发送成功客户端未收到。 客户端 SDK 在收到推送后,回调服务端接口,发送收到推送的回执;服务端收到客户端回执后,标记消息状态为发送成功客户端已收到。 对于推送过程中可能出现的异常情况,总结如下: 在调用第三方推送服务接口时,可能出现调用失败的情况;此时需要标记消息的状态为发送失败,开奖,留待重发。 在调用第三方推送服务接口成功后、第三方推送服务在下发至客户端的过程中,可能由于某种原因,造成客户端无法收到消息;此时消息的状态为发送成功客户端未收到,对于这种状态,需要重发。 客户端在收到推送的消息后、向服务端发送 ACK 回执时,可能由于网络环境的问题,造成服务端没有收到客户端发送的回执,此时消息的状态为发送成功客户端未收到,对于这种状态,需要重发。 消息在重发 N 次(N 次可配置)、仍然没有进入发送成功客户端已收到的状态,那么将不再进行自动重发;管理界面将提供手动重发消息的操作入口,如有需要,可以手动再进行重发。监控平台对于一直重复不成功的消息会报警通知操作人员,这样操作人员可以及时通过手动方式处理。 根据消息发送流程,可以得到消息在生命周期中状态的变迁如下图:
图 4:消息状态机 重发机制 消息重发主要存在三种场景:系统启动时,查询所有的发送失败或发送成功未收到客户端回执的消息,加载到推送队列重发;系统运行时,后台线程定时查询需要重发的消息,进入推送队列;手动触发时,直接将消息加入推送队列。 由于消息推送中间件服务通常要求高可用,为分布式部署,消息重发必须保证在单一节点执行,且保证只发送一次。需采用分布式锁的方式,保证重发只发一次,主流实现方式有三种: ZooKeeper:通过竞争创建临时节点的方式获取锁。 Redis:Redlock 是 Redis 作者的提出了一种分布式锁的算法,基于 Redis 实现,该算法实现了一种更安全、可靠的分布式锁管理。 数据库:如使用 MySQL 的 GET_LOCK 函数 对于每种锁机制的特点本文不详细介绍,根据实际应用需要任选一种即可。 由于 iOS 平台和 Android 平台的差异,消息重发需要考虑平台差异性。 使用第三方推送时,如果 iOS 应用在前台运行,那么将通过第三方推送维护的长连接,以透传的方式直接下发到 APP,称为应用内消息;而当 APP 在后台时,则第三方推送将消息推送到 APNs,由 APNs 推送到 APP,称为 APNs 通知。当通过 APNs 推送时,手机在收到消息后将在顶部的通知栏出现相关推送内容,这一行为是系统级别的,APP 无法控制。可能会出现这一问题:当 APP 在后台或者手机锁屏的情况下,如果服务端重发了消息,手机的通知栏将出现多条通知。 (责任编辑:本港台直播) |