消息推送策略设计

    在我们平时开发app的时候,消息推送是不可避免的,我们可能会使用GCM,JPUSH等第三方的消息推送服务,解决推送效率和质量问题,但业务端面的推送策略仍然需要我们自己来设计和开发。

    举个例子: 极光推送在推送消息时只有当用户在线时,消息才会推送到app上,但如果不在线呢,消息就不再推送了,这个需要我们自己处理,另外它都是实时的推送,并没有定时推送功能,所以在我们大多数业务场景里,这些逻辑是需要我们自己开的。现在我们来看一下实际的业务场景:

    1.公司正在开的一个快车的业务,乘客通过app下单后,会推送消息给管理员,我们假设管理中中是实时在线,这个没有问题;

    2.管理员看到有新的订单后,将订单指派给司机,此时司机可能不在线,所以我们在业务端另外新增短信发送,司机收到消息后打开app确认已经看到订单了,确认后推送消息给管理员,管理不再为乘客另派司机;

    3.同时,系统将会推送一条消息给乘客,表示有司机接单,并告知乘客司机将会在哪个时间点到达;

    上面的过程,有四次消息推送,在理想的情况下,这些业务可以跑通的。但实际上,就会产生一些问题。

    问题1:系统管理员某个时间点,因为网络问题不在线,收不到消息,实时推送失败后,不再重发,等网络好了以后因为没有消息过来,而忘记去处理订单,那很有可能就不能及时派单;

    问题2:司机也是同样的情况,没有收到消息,即使网络好了,司机也无法及时处理订单,很可能被系统管理员重新派单;

    问题3:乘客端的问题更明显,很多人下完单就做别的事情去,很可能app也关掉了,消息收不到很正常,如果消息有约定的比较重要的信息,很可能就被忽略了;

 

    所以,我们需要一种机制能保证,消息在我们的可控范围内,下面我们定义四种消息策略;

    1, 即时消息,推送完成即可,消息未成功也就不管了;

    2,延时消息,等一定时间后再发,这些也是最常用的,一般来说,某事件前多少分钟这种需求很常见,一个LRU的定时队列即可;

    3,重要消息,没有发送成功必须重要,

    4,时效消息,消息没有发送成功在一定时间内需要重发,超过一定时间后不再重发;

 

    要完成以上策略,我们首先考虑的是在使用LRU队列,将最先需要发的消息插入在队列的头部,每次描和处理正在需要发送的消息即可,但同时再需要将数据持久化到数据库,否则服务重启数据就没了;每一条消息发送成功后都更新数据库中持久化的记录,防止重启后重发;下面是大概流程:

    接收到要发的消息后,先判断是消息类型:

    1.即时消息直接发送, 并将发送记录写入数据库;

    2.延时消息插入队列,并写入数据库,等待扫描器触发,触发后发送消息后,移除队列数据并更新数据记录;

    3.重要消息直接发送,发送失败插入队列,并写入数据库,等待扫描触发,触发后发送消息成功后更新数据记录,失败则更新重试次数,等待一下次扫描触发,直到成功为止;

    4.时效消息直接发 送,发送失败插入队列,并写入数据库,等待扫描触发,触发后发送消息成功后更新数据记录,失败则更新重试次数,检查是否超过发送时效,超过则更新为已发送,未超过则继续等待一下次扫描触发;

    下面是定义的表结构

`message_id` varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '消息编号' ,
`message_alias` varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL '消息别名',
`message_tag` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL  '发送标记',
`message_type` varchar(11) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '消息类型 业务相关' ,
`message_modal` tinyint(1) NULL DEFAULT NULL COMMENT '消息模式 0 - 静默消息 1 - 弹出消息' ,
`message_title` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '消息标题' ,
`message_content` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '消息内容' ,
`message_extras` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '消息扩展内容' ,
`message_flag` mediumint(8) NULL DEFAULT NULL COMMENT '消息处理标志 0 - 未处理 1 - 已发送 2 - 发送失败 3 - 已超时' ,
`message_retries` mediumint(8) NULL DEFAULT NULL COMMENT '重试次数' ,

`message_time` int(11) NULL DEFAULT NULL COMMENT '发送时间‘
`message_blob` blob NULL ,
`create_time` int(11) NULL DEFAULT NULL COMMENT '创建时间' ,

 

    最后,我们需要创建一个定时,对队列进行扫描,另外程序重启的时候从数据库加载未发送的消息进行发 送;通过上面的过程一个消息发送的初级策略服务就基本完成了;那更进一步的设计就是当我们的消息服务不仅仅是为单个业务系统来服务的时候,我们就需要设计一些接口和标准来完成这些任务了。

    为了让业务从消息策略这一部分工作彻底的解放出来,我们需要定义一些规则,并将业务在组装消息过程也接管过来;当业务系统发送一个数据结构给消息推送系统后,我们需要将这个数据解析成一个消息记录再进行发送,但如果对每个业务的消息都进行解析,工作量就会比较大,所以我们需要定义一些接口,由业务接口解析消息的jar包,而消息推送服务需要通过配置进行加载即可,那么消息服务就只要开发一次,后续只需要进行配置即可;

    未完待续

 

转载于:https://www.cnblogs.com/the7year/p/5343028.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值