如何实现消息推送系统

1、前言

随着IOS,Android应用的普及,对推送消息的需求也越来来重要,目前市面上有的个推推送、极光推送、友盟推送等等,那如何自己搭建一个推荐系统昵?

2、名词说明:

设备端:消息接收方;

消息服务:负责和设备端建立连接,并推送消息给设备端

消息系统: 消息服务集群;

路由系统:根据消息服务的负责返回合适的消息服务给设备端(主要负责监控当前可用的消息服务、监控当前消费服务的负载情况,返回合适的消息服务给设备端)

业务系统:消息系统之外的其它业务系统;

平台:包括设备端和前端页面系统;

3、设计原则

可扩展性:为了保证系统的高可用,要求各模块都可以水平扩展;

高可用性:设计过程中必须考虑系统的稳定性;

原则单一:各组件的功能的单一(如:消息系统只负责和设备端连接和向设备端发送消息,禁止在消息系统中做复杂的业务逻辑)

4、技术选型

2.1:传输方式

要满足大量的连接数、同时支持双全工通信,并且性能也得有保障。

在 Java 技术栈中进行选型首先自然是排除掉了传统 IO

那就只有选 NIO 了,在这个层面其实选择也不多,考虑到社区、资料维护等方面最终选择了 Netty。

2.2:数据格式选型

1、json 简单

2、hession(为了简单说明,该文档就以hession为主)

3、protobuf

4、自定义协议

5、架构图

说明:

5.1、服务端启动说明(上面红色箭头标记)

启动包括两部分

1)注册服务到zk中;

2)监听MQ消息中,本机到消息。

5.2、客户端启动流程

客户端启动包括五部分

1)请求路由系统获取可用到消息服务;

2)路由系统获取可用到消息服务;

3)路由系统通过redis获取可用消息服务的负载,路由系统根据消息服务的负载返回合适的消息服务给设备端;

4)设备端连接消息服务;

5)消息服务接受连接服务,进行验证消息,向Redis中记录连接信息。

5.3、启动过程中需要考虑的几个问题

1)保证连接的稳定可靠(心跳)设备端和消息服务都进行必要的心跳检查。

当一台智能手机连上移动网络时,其实并没有真正连接上Internet,运营商分配给手机的IP其实是运营商的内网IP,手机终端要连接上Internet还必须通过运营商的网关进行IP地址的转换,这个网关简称为NAT(NetWork Address Translation),简单来说就是手机终端连接Internet 其实就是移动内网IP,端口,外网IP之间相互映射。

GGSN(GateWay GPRS Support Note)模块就实现了NAT功能,由于大部分的移动无线网络运营商为了减少网关NAT映射表的负荷,如果一个链路有一段时间没有通信时就会删除其对应表,造成链路中断,正是这种刻意缩短空闲连接的释放超时,原本是想节省信道资源的作用,没想到让互联网的应用不得以远高于正常频率发送心跳来维护推送的长连接。以中移动的2.5G网络为例,大约5分钟左右的基带空闲,连接就会被释放。

由于移动无线网络的特点,推送服务的心跳周期并不能设置的太长,否则长连接会被释放,造成频繁的客户端重连,但是也不能设置太短,否则在当前缺乏统一心跳框架的机制下很容易导致信令风暴(例如微信心跳信令风暴问题)。具体的心跳周期并没有统一的标准,180S也许是个不错的选择,微信为300S,本系统选择120s

设备端心跳检查流程

消费服务心跳流程:

说明:设备端和消息服务心跳过程中可能存在几个问题

1、消息不停端断开和重连

原因:设备端和消息服务相互断开重连;

解决方法:在redis中记录设备新建连接时间,如果连接是新建的,消费服务心跳次数检查调整为12次。

2、在redis中通一个客户端对应多个消费服务

原因:redis中消费连接信息按5分钟过期,心跳120s中进行一次,有可能断开连接没有清理完成前,设备端已经连接到另一个消费服务上了;

解决办法:在连接信息中记录最新更新信息,以最新更新信息到设备端为准(如果redis记录信息Key能定义唯一,不存在此问题)。

3、消息服务和redis中连接信息不一致

原因:由于不可预知原因

解决办法:  redis中消费连接信息过期时间为5分钟。

情况1:5分钟之后,消费服务客户端不会把消息推送到挂掉的消息服务服务器。

情况2:  5分钟以内的消息,

1、如果消息系统挂起,说明连接已经断开,设备端会重新建立连接,在建立连接时,设备端传入上次最后一条消息,系统推送上次最后一条消息之后的所有消息给设备端;

同时,设备端接受到消息,根据消息发送到时间和消息id进行去重和重排序,保证消息到唯一和顺序性;

2、消息服务如果收到本地连接不存在的消息,重新推送消息到MQ中;

4、连接建立和连接断开的业务处理逻辑和消息系统耦合

原因:连接建立和连接断开 只有消息系统清楚;

解决办法:消息系统建立连接和断开连接发送消息给MQ,业务系统监控MQ,进行业务处理。

5、消息系统挂机,redis中包含连接信息;

解决办法:监听zk中节点事件,当节点下线之后,同时删除redis中连接信息

5.4、发送消息

发送消息流程图:

说明:

平台:包括设备端,页面,各种第三方服务。

步骤:

1、平台根据业务需求请求业务系统(如:手机向电视发送消息,发起视频通话)

2、业务系统处理完业务逻辑,调用消息服务客户端;

3、消息服务客户端处理消息

3.1、获取消息应该发送到哪个topic下(如果获取不到相应到topic只写数据(可能设备端已经下线),不写MQ);

3.2、保存消息到mysql数据库中(只有消息写入数据库成功才返回平台消息发送成功);

3.3、向MQ中写入消息;

4、消费服务监听MQ消息,推送消息给设备端 (如果消息不在当前线程中,则重新用消息服务客户端 发送到MQ中,如果连续发送3次都没找到设备端,(设备端已下线)直接丢弃消息),

回写消息状态到mysql数据库

6、 监控系统

监控指标:1、各服务消息的系统性能;2、各服务消息的连接数;3、各服务消息的推送消息数据和推送的消息结果,4、推送消息日志(可以用log4j接入elk) ,5、路由系统的监控;

原文地址:https://www.cnblogs.com/smileIce/p/11156403.html

时间: 2024-11-09 18:23:52

如何实现消息推送系统的相关文章

MPush开源消息推送系统:简洁、安全、支持集群

引言 由于之前自己团队需要一个消息推送系统来替换JPUSH,一直找了很久基本没有真正可用的开源系统 所有就直接造了个轮子,造轮子的时候就奔着开源做打算的,只是后来创业项目失败一直没时间整理 这一套代码,最近比较闲就拿出来给开源做点贡献. 作为Java版的开源推送系统,MPUSH还是有很多不错的设计的,特别是对想自己搭建一套推送系统的团队 是有很大的借鉴意义的.当然开源出来也是不想曾经做过的工作白白浪费掉,特别希望对这方面有兴趣的同学 来一起把这套东西做的更好,服务更多的用户! 项目主页 http

开源实时消息推送系统 MPush

系统介绍 mpush,是一款开源的实时消息推送系统,采用java语言开发,服务端采用模块化设计,具有协议简洁,传输安全,接口流畅,实时高效,扩展性强,可配置化,部署方便,监控完善等特点.同时也是少有的可商用的开源push推送系统. 特性和优势 源码全部开放,包括server.android.ios .websocket等 代码质量高,全部模块化设计,真正的商用级产品,考虑到推送中遇到的大部分场景 安全性高,基于RSA精简的加密握手协议,简单,高效,安全 支持断线重连,及弱网下的快速重连,无网络下

设计一个百万级的消息推送系统

原文链接:https://crossoverjie.top/2018/09/25/netty/million-sms-push/ 前言 首先迟到的祝大家中秋快乐. 最近一周多没有更新了.其实我一直想憋一个大招,分享一些大家感兴趣的干货. 鉴于最近我个人的工作内容,于是利用这三天小长假憋了一个出来(其实是玩了两天??). 先简单说下本次的主题,由于我最近做的是物联网相关的开发工作,其中就不免会遇到和设备的交互. 最主要的工作就是要有一个系统来支持设备的接入.向设备推送消息:同时还得满足大量设备接入

如何使用Netty技术设计一个百万级的消息推送系统 原 荐

先简单说下本次的主题,由于我最近做的是物联网相关的开发工作,其中就不免会遇到和设备的交互. 最主要的工作就是要有一个系统来支持设备的接入.向设备推送消息:同时还得满足大量设备接入的需求. 所以本次分享的内容不但可以满足物联网领域同时还支持以下场景: 基于 WEB 的聊天系统(点对点.群聊). WEB 应用中需求服务端推送的场景. 基于 SDK 的消息推送平台. 技术选型要满足大量的连接数.同时支持双全工通信,并且性能也得有保障. 在 Java 技术栈中进行选型首先自然是排除掉了传统 IO. 那就

一篇文章教你如何设计一个百万级的消息推送系统

前言 先简单说下本次的主题,由于我最近做的是物联网相关的开发工作,其中就不免会遇到和设备的交互. 最主要的工作就是要有一个系统来支持设备的接入.向设备推送消息:同时还得满足大量设备接入的需求. 所以本次分享的内容不但可以满足物联网领域同时还支持以下场景: 基于 WEB 的聊天系统(点对点.群聊). WEB 应用中需求服务端推送的场景. 基于 SDK 的消息推送平台. 技术选型 要满足大量的连接数.同时支持双全工通信,并且性能也得有保障. 在 Java 技术栈中进行选型首先自然是排除掉了传统 IO

设计一个百万级的消息推送系统----转

技术选型 要满足大量的连接数.同时支持双全工通信,并且性能也得有保障. 在 Java 技术栈中进行选型首先自然是排除掉了传统 IO. 那就只有选 NIO 了,在这个层面其实选择也不多,考虑到社区.资料维护等方面最终选择了 Netty. 最终的架构图如下: 协议解析 既然是一个消息系统,那自然得和客户端定义好双方的协议格式. 常见和简单的是 HTTP 协议,但我们的需求中有一项需要是双全工的交互方式,同时 HTTP 更多的是服务于浏览器.我们需要的是一个更加精简的协议,减少许多不必要的数据传输.

服务器与客户端消息推送的原理

其实服务端与客户端实现消息推送的方式有几种: 1.客户端不断的查询服务器,检查新的内容,也就是所谓的pull或者轮询的方式: 2.客户端与服务器之间维持一个TCP/IP长连接(在HTTP1.1中,所有的请求都认为是长连接),服务器向客户端push: 3.当服务端有新内容的时候,发送一条类似短信的信令给客户端,客户端收到货从服务器下载新内容,也就是SMS的推送方式: 对于第一种方式有以下的缺点: 1.因为需要不断地轮询,所以手机会很耗电: 2.容易被系统杀死: 对于第二种方式: 我们首先来了解一下

Android与iOS系统的消息推送机制

相信大家在使用iPhone版微信的时候都会有这样的经历,微信已经处于关闭状态了(后台进程运行一段时间就被系统杀掉),这时候我们收到了一个消息提醒,打开微信应用,微信显示“连接中…”和“收取中…”,然后再次显示一次刚才系统推送给我的消息通知.对这个现象比较好奇,于是去知乎上查一下资料,发现知乎上的热心人还真多,看了大家的回答之后,总结如下: [之所以去知乎查看技术问题,因为我并非技术人员,而知乎上很多开发人员是会用通俗易懂的方式解释好技术问题的,因为里面有不少大牛.] 先介绍一下两个重要的消息推送

Android消息推送:手把手教你集成小米推送

前言 在Android开发中,消息推送功能的使用非常常见. 为了降低开发成本,使用第三方推送是现今较为流行的解决方案. 今天,我将手把手教大家如何在你的应用里集成小米推送 该文档基于小米推送官方Demo,并给出简易推送Demo 看该文档前,请先阅读我写的另外两篇文章: 史上最全解析Android消息推送解决方案 Android推送:第三方消息推送平台详细解析 目录 1. 官方Demo解析 首先,我们先对小米官方的推送Demo进行解析. 请先到官网下载官方Demo和SDK说明文档 1.1 Demo