后台回复“面试” “资料” 领取一份干货,数百整理的大厂技术面试手册等你 开发者技术前线 ,汇集技术前线快讯和关注行业趋势,大厂干货,是开发者经历和成长的优秀指南。
为什么阿里巴巴这一次能扛得起 11 亿的流量?
支付宝 App 架构的原理与实战
网易云音乐的消息队列改造,到底做了啥?2020年必学的 10 大算法
爱奇艺的实时数据架构到底有多牛?
在看 真爱
来自:京东技术团队
每个app或者业务都有将信息推送到用户客户端的需求。作为中台的推送平台,需要为公司内部许多个不同app同时提供可用,稳定的推送服务,因此我们消息推送平台应运而生。
名词解释:
dt:全称deviceToken,代表设备唯一标识。
appId:用户在推送平台申请的应用代号。
token:平台上每个应用对应的专属密钥。
msgId:每次推送调用,平台生成的消息唯一标识。
平台侧服务:
send-pservice:对外提供推送平台网站,用户可以在网站上进行申请应用,创建推送,查看数据等操作。
send-api:对外提供接口服务,包括JSF和http两种方式,接口包含推送,解绑,注销等。
send-worker:主要负责拉取定时推送,进行发送。
通道侧服务:
habitat:负责设备数据库的相关操作,包括绑定,解绑,上报,注销等。
mutate:负责接收推送请求,处理推送的pin,dt对应关系,及推送通道的适配。
report:上报服务,负责接收设备首次登录时,生成的dt上报。
channel:负责发送最后的推送请求到各个推送通道。
slark:回执服务,负责接收部分厂商通道推送后的异步回执信息,并做后续处理。
其他:
自建通道:由平台搭建的推送通道服务,负责维护长连接,推送消息到客户端。
厂商通道:由外部厂商提供的系统级推送服务。
DataAnalysis:平台的数据统计服务,负责统计推送的流转数据。
业务方进行推送有两种方式,一个是通过推送平台网站在页面上创建推送,第二个是通过调用我们提供的api服务的方式,进行推送。推送类型分为广播和指定用户推送,用户可用在创建推送的时候指定类型,指定人群或者设备。
平台内部收到消息推送的请求后,请求内如果是以设备形式推送,系统会直接将推送内容和dt组合,推送给推送通道。如果请求是以人群pin方式推送,系统通过pin找到对应的所有有效设备,然后以内容加dt的方式进行推送。推送通道分为两种,自建通道和厂商通道。厂商通道是手机或者系统的厂商提供的系统级别推送通道,由手机系统维护,相对稳定。自建通道是我们自研的推送通道服务,通过自建通道服务与客户端之间维持的长链接,对在线设备进行推送。
在应用维度,消息推送平台是为不同的app提供推送服务,所以需要为每个app生成appId以及对应的token,用于业务方调用推送平台认证使用。
在设备维度,平台会存储dt,pin和appId的对应关系,用于具体推送消息的组建以及设备数据的维护。
在消息维度,平台对于每次业务方推送请求的调用,生成一个msgId,并返回给调用方,这个msgId会在整个推送过程中被携带,从推送平台生成,推送到自建或者厂商通道,触达到客户端,最后回执给推送平台。这种方式是对整个推送流程追踪的必备条件,方便排查问题和推送数据统计。
业务方推送可以通过平台页面创建,和调用send-api服务接口两种方式,后者的使用较为频繁。平台提供http和JSF两种接口调用形式,推送请求按照实时性分类,可以分为即时推送消息和定时推送消息。
对于要求即时推送的消息请求,api服务在接到有效调用后,会立即调用通道侧的推送接口进行推送。对于需要定时推送的消息,api服务会将任务写到redis的有序集合中。send-worker会定时拉取各个应用集合中的推送任务,并将到达推送时间的任务取出,进行封装,调用通道侧服务进行推送,得到成功回执后,将任务移除。
为了提高接口性能,除基础参数校验之外,其他请求处理流程均采用异步方式。使用线程池执行每次推送请求的处理过程,缩短响应时间。这样可以减小高并发大量请求时,因响应时间过长,导致的响应超时或者JSF线程池耗尽的情况发生。
2请求厂商通道通道侧在收到平台侧封装好的推送请求后,会筛选出dt,然后将消息内容体和dt组合在一起,去请求厂商通道。如果业务方传的是pin,系统则会根据对应关系定位到pin对应的dt集合。当有厂商回执清理dt,或者业务方调用解绑或者注销dt接口时,这个dt集合是动态实时更新的。对于一次推送到大量dt的相同消息体,也就是群推或者广播的情况,系统会将dt分组发送,以控制请求体的大小。
在高并发请求的情况下,请求厂商通道很可能出现厂商限流导致失败的情况。当请求失败出现后,系统都会去进行重试,但是这个时候的重试如果时间间隔太短,其重试是无意义的,厂商通道在这么短的时间内可能还是限流状态,重试间隔如果太长,又会降低请求的效率,还消耗系统的内存。
因此推送平台对于这种情况采用了可配置的重试策略,实现对重试的次数和重试时间间隔的动态调整配置,方便根据厂商通道的具体情况对重试机制进行热更新。
3长连接的建立与维护自建通道是消息推送平台自己搭建的长连接推送通道服务,目的是为无法接入厂商通道的设备提供有效的推送途径。
长连接的建立:
自建通道的长连接是基于TCP+TLS实现的。当客户端上线动作触发时,会向服务端机器发送请求,服务端接收到请求之后,会返回给客户端一个心跳参数,这个参数会作为双方无数据交互时的心跳间隔。此后,客户端在正常情况下,如果与服务端没有数据交互,也会定时发送心跳至服务端,双方长连接建立成功。
我们会根据实际的网络及服务器情况,动态适配heartbeatConfig参数,包括断开时间间隔Idle和心跳发送间隔heartbeat,都可以进行动态调整。
长连接的维护:
客户端的第一次请求触发onConnect动作后,服务端会把客户端ctx与自建通道集群的连接关系维护起来。当双方在Idle时间内既无数据交互,又无心跳链接时,服务端会判定该客户端下线,对应长连接已断开,客户端的所有连接记录会被自动解除。
在长连接过程中,可能出现网络断开导致客户端断连重连现象。即在Idle时间内,同一个客户端向服务端请求第二次建连,这时可能出现一个客户端与服务端建立两个长连接的情况。对于这种问题,服务端采用断开老连接,接受新连接的形式,保证集群中每台设备长连接的唯一性。
使用长连接进行推送:
当通道侧的channel服务受到最终的推送请求后,会将消息体和dt最终封装成请求通道的形式。对于使用自建通道的设备,channel会自动识别到该设备对应的服务器单机ip,将推送请求发送到对应机器进行推送。识别不到则判定设备不在线,无法进行推送。
自建长连接的安全保障:
对于自建通道的长连接服务来说,安全性是十分重要的。我们主要从两方面对安全性做了保障。第一个是自建通道使用TLS加密的服务端域名。第二个是使用自定义的编解码方式,在服务端和客户端SDK之间,我们统一使用事先规定好的自定义编码和解码方式,来提高数据层面的安全性。
4推送回执的处理每个厂商通道包括自建通道的回执参数标准都不统一,平台的slark服务用于接收推送通道的回执消息,目前接入回执服务的厂商包括华为,魅族,小米和OPPO。针对不同的通道,平台会根据每个通道的回执参数标准,为每个通道做单独的回执信息处理,例如根据返回码进行无效dt的清理,客户端打开推送后的流水发送(用于数据统计)等。
推送数据对于一个推送平台来说必不可少,这些数据既可以用于每个业务方查看自己每条推送的状态效果,方便他们更好的制定推送策略,同时也让每条推送有迹可循,方便了推送整个流程的问题排查。
推送状态包括处理,发送,触达,打开。消息处理和发送两个状态由通道侧处理节点生产到kafka,消息的触达和打开由SDK上报给厂商或者自建通道,再由通道回执给slark服务,生产到kafka。
推送平台对于消息推送提供了多维度的数据统计,包括对每台设备,每个用户的推送记录,还有群推和广播各个环节的总体数量统计,并体现触达率和打开率。
同时,还提供了推送通道维度的推送状况统计,以及近期推送走势图,可以让业务方从多个角度,清晰准确的观察到自己每条推送的结果。
设备数据方面,平台除了保存每条dt的详细对应关系外,还对于每个应用的设备总量,每日的新增设备,清理设备,关闭设备进行了单独统计和展示。同时也提供了手机品牌(安卓),型号(IOS)维度的设备数据统计。
技术实现方面,数据的统计使用了flink计算程序,通过全流程携带的msgId,消息类型,推送状态以及客户端上报的设备类型等字段,计算出各个维度的推送数据。在每台设备这个维度的推送数据方面,使用了elasticSearch,对推送数据的必要字段进行了落地,支持用户以pin的形式,查询对应所有设备的推送情况。
对于一个成熟的平台化产品,对于自身业务及服务的监控和报警必不可少。消息推送平台在内部系统,用户使用需求两个方面都设置了详细的监控埋点,制定了可靠的报警规则。
在内部系统方面,推送平台针对每个新建的应用都添加了appId对应的接口埋点监控,当接口的调用量,性能,可用率发生变化时,平台管理员会根据报警,找到对应的应用负责人,方便及时的了解情况,定位问题,解决问题。同时也对关键集群中的机器设置了内存,CPU报警规则,及时监控服务端集群性能。
此外平台还对于每个应用所上传的证书进行每日定时检查。由一个定时任务程序每天拉取所有应用证书,解析证书有效期,平台会对已经失效,或者还剩7天失效的证书应用负责人进行邮件,短信等形式的报警,以敦促用户尽快更换证书,避免问题出现。
提升系统性能,扩大服务范围:
目前消息推送平台已经为京东金融,京麦,京喜等应用提供消息推送服务,下一个目标就是为京东主站提供全量消息推送的服务。我们也将继续优化性能,提高系统的稳定性和可用率,打造一个优秀的大规模分布式消息推送平台。
与此同时,消息推送平台还将推进对外输出的工作。将上云,组件化的相关改造任务尽快完成,让推送平台可以对外赋能,服务到公司外部更多的用户群体。
在公众号,在后台回复关键字:666,可以获取一份程序员大礼包!
后台回复“面试” “资料” 领取一份干货,数百整理的大厂技术面试手册等你 开发者技术前线 ,汇集技术前线快讯和关注行业趋势,大厂干货,是开发者经历和成长的优秀指南。