年底这段时间一直在研究苹果的APNS(英文全称:Apple Push Notification Service)服务,进行了很多尝试,积累了一些经验。写出来总结一下,有不对的地方欢迎指正。
关于推送效率,苹果官方给出的建议是当建立一个Socket通道后,尽可能将需要推送消息和接受的devicetoken连续发送至APNS服务器端。
但是,这里需要注意如果消息队列中存在不正确的devicetoken时,苹果会在接受到这个devicetoken时,强制中断当前的Socket通道,这样会造成后面的消息无法正常发送给APNS服务器。
怎么办?
可能会有人建议每推送一条消息就断开Socket通道重新连接一次,来保证推送成功率。这样做成功率的确可以保证,但效率实在太低。
那怎么办?
很简单,我的做法是在一个消息队列中,每发送一条消息,就去read当前的Socket通道,苹果会在遇到错误的devicetoken后进行标记,我们可以read到这个数据,从而将错误的devicetoken从队列中剔除,并尝试重新建立一个Socket通道,然后从错误的devicetoken后面继续推送。
这样,我们就可以放心大胆的去连续推送一个消息队列,而不用担心由于错误的devicetoken造成推送半途中断。
还有什么办法可以提升推送效率?
最简单的办法就是多线程或多进程处理消息队列,我们团队的做法是多进程,通过HASH将一个消息队列平均分布到多个服务器端的进程上,从而进一步加快推送的速度。
采用多进程还有一个考虑,那就是担心若采用多线程万一遇到某些未知的异常,结果很可能是全军覆没,所有线程一起挂掉。而多进程的状态下,一个进程出现问题,其他的进程还可以继续工作,尽可能将影响降至最低。
速度还能再快吗?
没问题,速度还想进一步提升,就要从网络带宽和服务器方面下功夫了。用n台服务器组成一个消息推送阵列,通过某种策略来分担一定量级的推送任务,每台服务器中再通过前面提到的多进程方式运作,相信效率能够提升的非常明显。
关于feedback
APNS的feedback是一个非常贴心的服务,他会告诉你近期推送的消息,有哪些设备由于卸载了应用而无法在通知中显示消息。
那么,我们通过定期从feedback中获得这些devicetoken后,在数据库中进行标记,在下次的推送中,从消息队列中剔除这些devicetoken,这样减少了无用功,推送一次会完成的更快。
其他建议
本着不重复发明轮子的思想,推荐一下ApnsPHP这个开源项目,这里就不放链接了,github上搜吧:)
阳光部落原创,更多内容请访问http://www.sunbloger.com/