1.1 产品介绍
消息推送服务(Message Push Service,简称 MPS)是移动开发平台 mPaaS提供的专业的移动消息推送方案,针对不同的场景推出多种推送类型,满足客户的个性化推送需求。为了提升推送的到达率,mPaaS在MPS中集成了华为、小米等厂商的推送功能,在提供控制台快速推送能力的同时,也提供了服务端接入方案,方便用户快速集成移动终端推送功能,与App用户保持互动,从而有效地提高用户留存率,提升用户体验。
1.1.1 功能简述
如图6-1所示,可通过MPS发起多种类型的消息推送,推送通道支持自建通道和厂商通道,推送方式支持控制台页面推送和API推送,基于实际业务场景,选择合适的推送类型、推送通道以及推送方式。
图1‑1 MPS产品功能图
MPS核心功能如下:
(1)多种推送方式:可以精准推送消息给自定义目标用户群体、单个用户、全部用户等多种方式,并可以从移动推送服务控制台页面发送消息,也可以利用API接口发送消息。
(2)自定义消息有效期:若初次下发消息时设备未在线,那么在消息有效期内,设备建连或者发起用户绑定均可触发消息再次下行,确保消息最终送达目标用户。
(3)不同推送目标类型:可以建立设备与登录用户的对应关系,基于设备标识或用户标识推送消息。
(4)个性化消息模板:通过模板管理页面,您可以配置个性化模板,满足业务的个性化推送需求。
(5)推送配置:通过推送配置页面,配置证书,您可以选择 iOS 设备推送所对应的 APNs 网关。
(6)推送通道配置:接入厂商推送通道,集成华为、小米等厂商通道推送功能,提升推送到达率。
(7)密钥管理:MPS的所有对外接口都需要对请求进行签名,保证了业务的安全性,提供了密钥配置页面供用户配置自己的密钥。同时,提供消息回执功能,以便追踪消息的投递结果。
(8)使用分析:基于客户端埋点上报数据,在平台、版本、推送通道、推送类型、时间等维度上,对推送数据进行统计分析,生成分析报表,可展示分钟级别的统计结果。
1.1.2 基本原理
如图1-2所示,MPS推送服务为mPaaS体系内直接与客户端通讯的核心必备基础组件之一,其基础原理为基于TCP长连接通道或者手机厂商推送通道进行消息通知相关业务数据传输。
图1‑2 MPS原理图
客户端通过使用 mPaaS移动网关服务(MGS),调用RPC(Remote Procedure Call,简称RPC)进行设备注册、用户绑定以及厂商通道的关系绑定,实现基于设备维度和用户维度的消息推送。按照既定规范采集和上传客户端行为日志埋点,后端实时统计分析推送数据,生成统计报表。MPS同时支持API推送与控制台页面推送,您可以在自己的服务端根据业务逻辑通过 API调用推送个性化消息,也可以通过控制台页面直接推送消息。为了提升消息到达率,MPS支持接入华为、小米、FCM和APNs等推送通道,并对后端业务系统保持透明,可让业务系统专注于完成业务功能,无需关注终端机型。
1.1.3 价值优势
MPS具备以下优势:
(1)快速稳定:消息下发速度快,保证稳定到达。
(2)接入简单:降低接入成本,更高效。
(3)量化推送效果:集成推送数据统计,更智能地分析消息送达率,打开率,明确推送效果。
(4)精准个性化推送:
可以向单个用户、自定义用户分组等各种维度精准推送个性化信息。
提供控制台推送页面推送,满足简单的推送需求。同时,也提供服务端接入方案,满足更为复杂的需求。
提供消息回执,供您追踪消息下发结果,有效提升用户留存率跟活跃度。
建立设备标识与 App 用户体系的对应关系,可把 App用户名作为消息接收者直接发送消息,无论用户在哪台设备登录信息都能准确送达。
1.1.4 使用场景
消息推送的典型应用场景如下:
(1)营销活动向用户推送针对性的消息,包括营销活动、业务提醒等,以提升用户粘度。App 通过调用消息推送 API,对目标用户进行定向消息推送,以更主动的方式触达更多用户,吸引用户消费,从而提升最终营销活动转化效果。
(2)系统通知按照 App 服务端业务逻辑指定推送人群,直接将消息推送给目标设备。
针对不同应用场景,MPS 提供以下几种推送方式:
(3)极简推送(Simple Push):针对单个用户或设备快速推送消息,配置简单。
(4)模板推送(Template Push):针对单个用户或设备推送消息,可指定消息模板,消息正文由替换模板占位符得到。
(5)批量推送(Multiple Push):针对大量设备或者用户推送消息,可指定消息模板,在配置文件中针对不同设备或用户设置不同的占位符变量值。
(6)群发推送(Broadcast Push):针对全网设备进行推送,可指定消息模板,消息正文由替换模板占位符得到。
1.2 产品架构
如图1-3所示,App客户端启动上报设备ID和用户ID信息,到达mPaaSgw由注册中心通过dubbo/tr模式转发到yunpushcore,移动推送核心(yunpushcore)负责处理业务逻辑以及向业务端提供 API 接口;移动推送网关(Mcometgw):负责与Android客户端建立、保持推送长连接。
图1‑3 MPS产品架构图
1.2.1 推送渠道
MPS针对不同的手机厂商是有不同的消息推送方式,分为以下两种:
自建渠道:自建渠道是针对国内Android 机型,由mcometgw与客户端建立TCP长连接进行消息推送。
三方渠道:三方渠道是对大厂商Android 机和iPhone 机型,yunpushcore调用对应厂商的推送接口,通过三方厂商的推送服务器到达手机客户端。
1.2.2 服务依赖
启动依赖:yunpushcore启动时,会请求mAppCenter拉取元数据,与数据库中的数据做对比,将差异量入库。数据库挂掉会影响MPS提供服务。
运行时依赖主要分为四个部分:
(1) mAppCenter会聚合MPS的前端页面,前端界面上的请求会经由mAppCenter nginx路由到MPS。
(2)mcometgw提供自建渠道网关。
(3)设备在线状态依赖缓存(Tbase等)。
(4)所有客户端流量都经由mPaaSgw对外提供,设备上包、用户绑定及解绑。此处依赖zk或者配置中心。
1.3 网络架构
如图1-4所示,分为以下几个核心链路。
图1‑4 MPS网络架构图
1.3.1 RPC
客户端App上报设备ID和用户ID,经DNS解析、F5证书卸载,之后到达外网spanner负载均衡,之后转发到mPaaSgw,mPaaSgw通过TR/DUBBO协议转发到yunpsuhcore。
1.3.2 消息推送
客户端App(国内Android)通过DNS->F5证书卸载->stream反代,与mcometgw建立TCP长链接。mcometgw同时也与yunpsuhcore保持长链接。客户端在线或者断线都会及时同步到yunpsuhcore,并对应存储到缓存TBase中。
用户可以通过mAppCenter 或业务系统调用API,到yunpsuhcore发起消息推送。mAppCenter的配置信息和数据会存储到OB数据库。
三方渠道推送,yunpsuhcore通过DNS劫持方式到内部DNS,到stream正代,stream到达公网三方网关,进而推送到客户端。
1.3.3 网络
(1)对客户端服务的入口分为两个部分,组件网关对外提供RPC服务,mcometgw做自建渠道长链接网关,需要暴露在公网。
(2)公网出口需要访问苹果、小米、华为三方网关。所以要求采用DNS劫持的方式,将yunpushcore发往三方渠道的流量转送到DMZ区stream的F5,另外stream本身需要打通公网DNS,能够解析到公网三方渠道的域名,同时打通与对应域名的域名级别的ACL。如果行方此处方案不通过,需要提前告知行方DNS漂移服务不可用的风险。
(3)yunpushcore给行方业务系统会提供推送接口服务,所以此处需要给yunushcore申请内网F5负载,并申请内部域名供行方使用。
1.4 产品特点
(1)MPS针对不同手机厂商有不同的推送方式,分为以下两种:
①三方推送,目前主要针对苹果,华为和小米手机,走厂商自己的渠道进行推送。
②直接推送,主要针对国内安卓手机,由mcometgw与手机直接建立TCP长链接进行推送。
(2) 消息推送最终都是通过设备标识进行推送,因此如果需要用户维度的推送,要在用户登陆时将用户和设备进行绑定,当用户登出时,再将该绑定关系解绑。
(3) MPS的管控聚合在mAppcenter控制台上,页面上的请求都会经mAppcenter里的nginx路由。
(4) 缓存中保存客户端链接信息。
(5) 苹果,小米,华为的推送因为走他们自己的渠道,因此需要在控制台上进行对应的接入配置。苹果需要特别注意选择正确的证书,很容易混淆开发和生产。
1.5 常用日志
如图1-5所示,包含了MPS常用的运维日志目录,可用于日常运维问题排查使用。
图1‑5 MPS常用日志介绍
1. 绑定日志
推送绑定相关的日志,包含建立绑定关系、解绑、三方渠道绑定的日志。
1)日志路径
/home/admin/logs/yunpushcore/yunpushcore-bind-stat.log
2)日志示例
2022-05-13
16:56:46.425,bind,apiCall,self,2D005CA271131-sit,XNkvl0lfRGwDAC3IPgJx8+ug,216610000003345856723,-,android,#,1,7
2023-05-13 16:56:46.425,unbind,apiCall,self,2D005CA271131-sit,V3WygEz4sEoDAHUsqCI2G8RQ,216610000001564943541,-,-,#,1,10
3)日志格式说明
日志格式如表6-1所示。
表6‑1 绑定日志格式表
序号 |
内容 |
说明 |
0 |
2019-05-13 16:56:46.425 |
时间 |
1 |
unbind |
绑定类型 - bind(绑定) - unbind(解绑) |
2 |
apiCall |
调用类型 - API 调用 - cleanCall |
3 |
self |
关系类型 |
4 |
2D005CA271131-test1 |
appCode |
5 |
V3WygEz4sEoDAHUsqCI2G8RQ |
自建渠道的 token |
6 |
216610000001564943541 |
用户 ID(userId) |
7 |
- |
三方渠道 token |
8 |
- |
系统类型 |
9 |
### |
分隔符 |
10 |
1 |
分钟级别调用总次数 |
11 |
10 |
分钟级别调用总耗时 |
2. 推送结果摘要日志
该日志记录推送的每条消息结果。
1)日志路径
/home/admin/logs/yunpushcore/yunpushcore-notify-digest.log
2)日志示例
2022-5-15 00:01:13.329,mpaas-pushcore-1-6,-,216610000017981521332,de7aa299e35573a3d333794257f1eee70396ea5469473321b6cbd037f2bf6a36,6CC59C4231550-prod,IOS,iOS,1.2.0,TEMPLATE,201910151115113000166339590886559_MSG_SEND_0,_0_0_296782f508e146f9d707332,391153259,DEFAULT_USER_PUSH,200,true,true,2,ACKED,927
3)日志格式说明
日志格式如表6-2所示。
表6‑2 推送结果摘要日志格式表
序号 |
内容 |
说明 |
0 |
2022-5-15 00:01:13.329 |
时间 |
1 |
mpaas-pushcore-1-6 |
机器地址 |
2 |
- |
traceId |
3 |
216610000017981521332 |
userId |
4 |
de7aa299e35573a3d333794257f1eee70396ea5469473321b6cbd037f2bf6a36 |
token |
5 |
6CC59C4231550-prod |
appCode |
6 |
IOS |
操作系统类型 |
7 |
iOS |
平台类型 |
8 |
1.2.0 |
客户端版本 |
9 |
TEMPLATE |
推送类型 |
10 |
201910151115113000166339590886559_MSG_SEND_0 |
业务方消息 ID |
11 |
_0_0_296782f508e146f9d707332 |
数据库消息 key |
12 |
391153259 |
任务 ID |
13 |
DEFAULT_USER_PUSH |
模板名称 |
14 |
200 |
调用结果码 |
15 |
true |
推送调用结果 |
16 |
true |
业务结果 |
17 |
2 |
消息状态码 |
18 |
ACKED |
消息状态名称 |
19 |
927 |
时长 |
3. 推送结果统计日志
推送消息结果的统计日志。
1)日志路径
/home/admin/logs/yunpushcore/yunpushcore-notify-stat.log
2)日志示例
2022-05-14 11:28:51.120,IOS,570DA89111847-test,iOS,1.0.0.0,570DA89111847_IOS-test,SIMPLE,-,-,200,true,true,2,ACKED,2.1.0,-,#,1,365
3)日志格式说明
日志格式如表6-3所示。
表6‑3 推送结果统计日志格式表
序号 |
内容 |
说明 |
0 |
2022-5-14 11:28:51.120 |
时间段 |
1 |
IOS |
渠道 |
2 |
570DA89111847-test |
appcode |
3 |
iOS |
操作系统平台 |
4 |
1.0.0.0 |
客户端版本 |
5 |
570DA89111847_IOS-test |
平台 |
6 |
SIMPLE |
推送类型 |
7 |
- |
任务 ID(taskId) |
8 |
- |
模板 |
9 |
200 |
调用结果码 |
10 |
true |
推送调用结果 |
11 |
true |
业务结果 |
12 |
2 |
消息状态码 |
13 |
ACKED |
消息状态名称 |
14 |
2.1.0 |
推送 SDK 版本(push sdkVersion) |
15 |
- |
场景名称 |
16 |
### |
分隔符 |
17 |
2 |
分钟级别调用总次数 |
18 |
7 |
分钟级别调用总耗时 |
4. 建连日志
记录自建渠道的建连信息。
1)日志路径
/home/admin/logs/yunpushcore/yunpushcore-link-create.log
2)日志示例
2022-5-15 14:19:38,568 - ce100ec5016d1000800030300a19438d758,10705D3271509-test,843306747736386|780325551057905,10705D3271509-test,3g,516806,E8037,2.1.0,com.ates,10.28.253.197_1571120378#6029315,ce100ec5016d1000800030300a19438d758
3)日志格式说明
日志格式如表6-4所示。
表6‑4 推送建联日志格式表
序号 |
内容 |
说明 |
0 |
2022-5-15 14:19:38,568 |
时间 |
1 |
ce100ec5016d1000800030300a19438d758 |
建连时传递的自建 AdToken |
2 |
10705D3271509-test |
appCode |
3 |
843306747736386 |
780325551057905 |
4 |
10705D3271509-test |
appKey |
5 |
3g |
连接类型 |
6 |
516806 |
厂商(manufacturer) |
7 |
E8037 |
机型 |
8 |
2.1.0 |
推送 SDK 版本信息) |
9 |
com.ates |
应用包名 |
10 |
10.28.253.197_1571120378#6029315 |
网关 ID_网关路由信息#网关路由扩展信息 |
11 |
ce100ec5016d1000800030300a19438d758 |
下发自建 AdToken。在 1.10.x 之前的版本中,10 和 11 字段连在一起。 |
5. 断连日志
记录自建渠道断连信息。
1)日志路径
/home/admin/logs/yunpushcore/yunpushcore-link-close.log
2)日志示例
2022-5-15 14:20:19,825 - 10.28.253.197_1571120378#6029315,clientc,41
3)日志格式说明
日志格式如表6-5所示。
表6‑5 推送断联日志格式表
序号 |
内容 |
说明 |
0 |
2022-5-15 14:20:19,825 |
时间 |
1 |
10.28.253.197_1571120378#6029315 |
网关 ID_网关路由信息#网关路由扩展信息 |
2 |
clientc |
断连原因 |
3 |
41 |
连接存活时间(单位:秒)。此字段在 1.10.x 产品集版本中添加。 |
6. 回调日志
在开启回调功能的情况下,该日志输出所有回调信息。
1)日志路径
/home/admin/logs/yunpushcore/yunpushcore-push-callback.log
2)日志示例
2022-5-15 14:48:59,616 - (84EFA9A281942-default,false,pushLogout_79f08ce1a01d784d37515778e65ff811aa65bb979a8a270c4df3ec6bedcf1a5b,2,Acked,79f08ce1a01d784d37515778e65ff811aa65bb979a8a270c4df3ec6bedcf1a5b,{"adToken":"79f08ce1a01d784d37515778e65ff811aa65bb979a8a270c4df3ec6bedcf1a5b","osType":"ios"})
3)日志格式说明
日志格式如表6-6所示。
表6‑6 回调日志格式表
序号 |
内容 |
说明 |
0 |
2022-5-15 14:48:59,616 |
时间 |
1 |
84EFA9A281942-default |
appCode |
2 |
false |
是否过期 |
3 |
pushLogout_79f08ce1a01d784d37515778e65ff811aa65bb979a8a270c4df3ec6bedcf1a5b |
业务方消息 ID |
4 |
2 |
消息状态码 |
5 |
Acked |
消息状态码名称 |
6 |
79f08ce1a01d784d37515778e65ff811aa65bb979a8a270c4df3ec6bedcf1a5b |
目标 ID(用户 ID 或者设备 ID,取决于使用的推送方式) |
7 |
{“adToken”:”79f08ce1a01d784d37515778e65ff811aa65bb979a8a270c4df3ec6bedcf1a5b”,”osType”:”ios”} |
扩展信息 |
7. RPC日志
客户端 RPC 结果日志,包含绑定、解绑、上报的结果。
1)日志路径
/home/admin/logs/yunpushcore/yunpushcore-rpc.log
2)日志示例
2022-01-21 11:38:12,215 - [bind]bind begin, reqPb=BindInfoReqPb[appId=459039B251054,workspaceId=default,userId=PB19661895,deliveryToken=c4f317c3016d1000bb1430300a1c254c4wM,osType=1]
2022-01-21 11:38:12,224 - [bind]bind end, reqPb = BindInfoReqPb[appId=459039B251054,workspaceId=default,userId=PB19661895,deliveryToken=c4f317c3016d1000bb1430300a1c254c4wM,osType=1],result=ResultPb[success=true,code=100,message=<null>],consume=9
2022-01-21 11:41:01,193 - [bind]bind begin, reqPb=BindInfoReqPb[appId=363452B111425,workspaceId=default,userId=368803581790,deliveryToken=58aa5a235197c52be5137a7d9df524e8ad427ae923a70921abcf0ae538a8cea0,osType=2]
2022-01-21 11:41:01,202 - [bind]bind end, reqPb = BindInfoReqPb[appId=363452B111425,workspaceId=default,userId=368803581790,deliveryToken=58aa5a235197c52be5137a7d9df524e8ad427ae923a70921abcf0ae538a8cea0,osType=2],result=ResultPb[success=true,code=100,message=<null>],consume=9
2022-01-21 11:41:16,155 - [report]report begin, deviceInfo=DeviceInfoReqPb[appId=363452B111425,workspaceId=default,deliveryToken=80435d94f656eb9e81d7e367d75dcdea4cb5e2c8c2dfd44f87c4f4469ab8e3ce,osType=2,imei=46002,imsi=46002,appVersion=5,connectType=4G,model=iOS,thirdChannelDeviceToken=<null>,thirdChannel=0,channel=App Store,pushVersion=2.1.0]
2022-01-21 11:41:16,160 - [report]report end,deviceInfo=DeviceInfoReqPb[appId=363452B111425,workspaceId=default,deliveryToken=80435d94f656eb9e81d7e367d75dcdea4cb5e2c8c2dfd44f87c4f4469ab8e3ce,osType=2,imei=46002,imsi=46002,appVersion=5,connectType=4G,model=iOS,thirdChannelDeviceToken=<null>,thirdChannel=0,channel=App Store,pushVersion=2.1.0],result=ResultPb[success=true,code=100,message=<null>],consume=5
2022-01-21 11:40:43,297 - [unbind]unbind begin, unbindReqPb=UnbindReqPb[appId=8EA2333231523,workspaceId=default,userId=1100000000346563,deliveryToken=13fb96a7016d1000aba430300a51322e968]
2022-01-21 11:40:43,307 - [unbind]unbind end, reqPb = UnbindReqPb[appId=8EA2333231523,workspaceId=default,userId=1100000000346563,deliveryToken=13fb96a7016d1000aba430300a51322e968],result=ResultPb[success=true,code=100,message=<null>],consume=9
3) 日志格式说明
日志格式如表6-7所示。
表6‑7 RPC日志格式表
序号 |
内容 |
说明 |
0 |
2023-01-21 11:38:12,215 |
时间 |
1 |
[bind][report][unbind] |
标识绑定、上报或解绑。 |
2 |
begin,end |
标识请求的开始和结束,结束会有请求结果 ResultPb |
3 |
reqPb |
请求体 |
4 |
result |
返回结果 |
5 |
osType |
操作系统类型: 1 表示 Android 2 表示 iOS |
8. 流量日志
该日志是针对 MPS 所有请求的统计日志。
1) 日志路径
/home/admin/logs/yunpushcoreyunpushcore-flow-stat.log
2) 日志示例
2022-06-08 11:49:40.106,INTO,C53EF20111717-sit,REPORT_LOCAL,#,46
2022-06-08 11:49:40.106,INTO,C53EF20111717-sit,BROADCAST_GLOBAL_APP,#,1
2022-06-08 11:50:40.106,INTO,C53EF20111717-sit,REPORT_LOCAL,#,1
2022-06-08 11:50:40.106,INTO,C53EF20111717-sit,BROADCAST_GLOBAL_APP,#,1
2022-06-08 11:51:40.106,INTO,C53EF20111717-sit,BIND_LOCAL,#,44
2022-06-08 11:51:40.106,INTO,C53EF20111717-sit,REPORT_LOCAL,#,47
2022-06-08 11:51:40.106,INTO,C53EF20111717-sit,BROADCAST_GLOBAL_APP,#,1
2022-06-08 11:53:40.106,INTO,C53EF20111717-sit,BIND_LOCAL,#,4
2022-06-08 11:53:40.106,INTO,C53EF20111717-sit,REPORT_LOCAL,#,7
2022-06-08 11:53:40.106,INTO,C53EF20111717-sit,BROADCAST_GLOBAL_APP,#,1
2022-06-08 11:55:40.106,INTO,C53EF20111717-sit,BIND_LOCAL,#,4
2022-06-08 11:55:40.106,INTO,C53EF20111717-sit,REPORT_LOCAL,#,3
3) 日志格式说明
日志格式如表6-8所示。
表6‑8 流量日志格式表
序号 |
内容 |
说明 |
0 |
2022-06-08 11:49:40.106 |
时间 |
1 |
INTO |
INTO:流入 |
2 |
C53EF20111717-sit |
appCode |
3 |
REPORT_LOCAL |
业务 |
4 |
### |
分隔符 |
5 |
46 |
数量 |
9. 消息日志
该日志记录非安卓群发的推送消息。
1) 日志路径
/home/admin/logs/yunpushcore/yunpushcore-push-message.log
2) 日志示例
2022-06-22 12:35:56,965 - (CE1DDD2281521-dev,102276561,0,3,-1,_0_0_68671c2a9939f
926be63106,2566448556875523,163418044251106,187,{"silent":false,"action":"0","id
":"1566448556875521","title":"交易通知","params":{"test":"自定义扩展参数"},"cont
ent":"微信客户成功支付16.0元","url":"http://127.0.0.1"})
3) 日志格式说明
日志格式如表6-9所示。
表6‑9 消息日志格式表
序号 |
样例 |
说明 |
1 |
2022-06-22 12:35:56,965 |
时间 |
2 |
CE1DDD2281521-dev |
APP-workspace |
3 |
102276561 |
任务 ID(taskID) |
4 |
0 |
任务类型: |
5 |
3 |
推送类型: |
6 |
-1 |
模板 ID(简单推送没有模板,所以为 -1) |
7 |
_0_0_68671c2a9939f |
消息 ID |
8 |
2566448556875523 |
业务消息 ID |
9 |
163418044251106 |
用户或设备 ID |
10 |
187 |
消息(payload)的长度 |
11 |
{“silent”:false,”action”:”0”,”id |
消息 |