移动互联网时代,消息推送(Push)服务成为App应用不可或缺的重要组成部分,推送服务可以提升用户的活跃度和留存率。我们的手机每天接收到各种各样的广告和提示消息等大多数都是通过推送服务实现的。
推送服务可以按照技术实现不同主要分为以下2类:
自建通道,当APP处于前台时,推送的消息可以通过自建的网络长连接通道推送过来, 本文重点介绍的是自建通道的技术选型以及实践。
专有通道:当APP在离线(kill掉进程、切到后台、锁屏)时,收到的消息提醒,比如IOS系统中,这种Push需要经过苹果的APNS服务器才可以推送到某台设备的某个APP上的,Google也有相应的推送GCM服务。该Push与设置中是否打开“通知”专有通道。
使用的网络主要是运营商的无线移动网络,网络质量不稳定,例如在地铁上信号就很差,容易发生网络闪断;
大量的客户端接入,而且通常使用长连接,无论是客户端还是服务端,资源消耗都非常大;
由于谷歌的推送框架无法在国内使用,Android的长连接是由每个应用各自维护的,这就意味着每台安卓设备上会存在多个长连接。即便没有消息需要推送,长连接本身的心跳消息量也是非常巨大的,这就会导致流量和耗电量的增加;
服务不稳定,消息丢失、重复推送、延迟送达、过期推送时有发生;
垃圾消息满天飞,缺乏统一的服务治理能力。
活动通知
目的是告诉用户某项活动或者重要的事情即将开始,希望用户参与,这类通知的文案比较重要,最大程度的吸引用户点击参与;
信息咨询
包含知识类、咨询类产品,通常以热点时事新闻、个性化订阅为主;
产品推荐
以促进购买转化为主要目的,多用于电商、金融类产品;
系统提示
显示产品用户曾经操作过的行为,例如支付成功、购买成功等,主要以描述事实、信息准确为最关键点。
在 Java 技术栈中要满足大量的连接数、同时支持双全工通信,并且性能也得有保障,在技术选型中自然排除掉传统BIO(阻塞I/O),选用NIO。
阻塞I/O:应用程序调用一个IO函数,导致应用程序阻塞,等待数据准备好。如果数据没有准备好,一直等待数据准备好了,从内核拷贝到用户空间,IO函数返回成功指示。
I/O复用:I/O复用模型NIO会用到select或者poll函数,这两个函数也会使进程阻塞,但是和阻塞I/O所不同的的,这两个函数可以 同时阻塞多个I/O操作。而且可以同时对多个读操作,多个写操作的I/O函数进行检测,直到有数据可读或可写时, 才真正调用I/O操作函数。
WebSocket 消息推送优点 :
开发周期短,维护成本低
消息不经转第三方服务器,直接由服务器发送到客户端,安全性好。基于 GCM 或者 APNS 的消息推送会把消息发送 GCM 服务器或 APNS 服务器,再由他们转发到客户端;
自己开发服务端,可扩展性好;
对于客户端而言,长连接比轮询的方式性能和及时性更好;
WebSocket 消息推送缺点 :
长连接浪费服务端资源;
不能后台运行,一旦 app 退出就不能收到通知;
由于服务器保持多个长连接,性能将会下降,最大连接数也会有限制。
综合考虑我们使用Netty作为网络通信层框架。
Netty的线程模型就是我们常说的Reactor模型,boss线程其实是一个独立的NIO线程池,用于接收client请求,默认线程 池大小为1,worker线程池用于处理具体的读写操作,默认线程池大小为2 * cpu个数。
PPDSocket推送服务平台系统主要分为3个子服务,分别为核心服务、业务服务和路由服务;
核心服务:提供双向通信的能力,处理建立连接,数据上报,指令下发,心跳消息等等;
业务服务:提供API接口,业务方调用API接口下发指令给客户端;
路由服务:主要用来路由寻找到某台指定的客户端与哪台netty服务器主机之间建立的连接。
以上各系统之间使用MQ消息,基于消息事件驱动方式交互通信。
首先客户端与服务端建立连接,然后客户端上报设备的信息,在服务端接收后以MQ消息发送给业务系统落库保存。
在业务服务API接口接收到推送指令请求,通过MQ方式通知路由服务,路由服务寻找到某台Netty服务器,通过TCP长连接发送给这台Netty服务器,Netty服务器收到消息后,将指令发送给具体的客户端。
要支持大量长连接,Linux操作系统内核参数需要优化,具体如下:
全连接队列和半连接队列解释:服务端调用listen函数监听端口的时候,内核会为每个监听的Socket创建两个队列:半连接队列和全连接队列。
TCP三次握手,两个队列如下工作:
Server收到Client的syn后,把相关信息放到半连接队列中;
Server回复SYN+ACK给Client;
Server收到Client的ACK,如果这时全连接队列没满,那么从半连接队列拿出相关信息放入到全连接队列中,3次握手成功,等待进程调用accept函数把连接取出来使用。
本文主要介绍了消息推送(Push)技术原理,以及在项目中的技术选型和实践,目前每天推送指令消息50万左右,推送到达率99.9%以上;每天高峰时期有1.5万台手机设备同时与系统建立长连接,其中1秒内推送到达占比60%以上,2秒内推送到达占比80%以上,后续考虑更多的业务场景接入。
lrt,信也科技移动应用中台借款研发服务端研发