个人对于即时通讯(推送)系统构建的一些拙见
今天有一个哥们在群里问关于手机即时通讯开发的事情,然后我们就开始聊上了,对此我也发表了一些自己的看法。
大家都知道在iphone端做及时通信很好做,因为苹果已经封装好了系统推送的接口,所有推送都是通过苹果服务器建立的那个唯一的socket连接。
但是放在android终端就有一些困难了,首先android在2.2才推出了c2dm服务,不过这个东西在中国这个地方似乎不怎么试用,首先手机的版本问题难以解决,然后就是定制化太严重。
所以对于android及时通信而言只能自己架设服务器完成这个事情了。
说道自己构建服务器就无可避免的谈到服务器负载,性能的一些问题,我首先想到的是p2p技术,这样服务器只负责打洞,可以大大的减少服务器压力。不过这一套似乎在移动终端很难实现,首先是移动终端的不稳定性,其次就是运营商对p2p做了限制,总之这条路在移动领域很难走通了。
后来有考虑用一些第三方的框架,比如android的第三方的androidpn,这些似乎服务器要求很高,一台64的linux服务器只能承载4W用户,即时最大优化也只能承载5W,那如果用户有100W不是需要20台服务器?这样对于很多公司而言都是一笔很大的成本。
然后我又思考了一下到底什么才是瓶颈,如果建立tcp长连接的话无疑是非常浪费服务器资源的,既然如此我就想到了另外的一种模式,那就是udp负责保持连接,tcp负责发送消息的模式。
大家都知道,udp不是面向连接的,所以理论上来讲一台服务器可以开无限个udp,而且udp消耗相对于tcp小,至于如何报错udp的不稳定性?我们可以把协议扩充一些比如时间戳,接收回执,失败重发,发送报文减小到一个包里面,等等.反正只作为通知用,报文不需要太大。
基于上面的理论,我假设有两台服务器一台负责udp保持连接,一台用于tcp发送消息。我们不需要tcp保持长时间连接,每次发送完成之后断开连接即可,我们甚至可以用http服务器作为消息发送容器。而udp服务器主要是用于心跳响应和通知终端去服务器取消息。
这样我们只需要测试tcp服务器最大的负载能力以及udp保持的最大连接数即可。如果是http服务器测试就更加方便了。至于服务器集群之类的我就不说了,老身长谈。
以上只是我个人的拙见,我也不是专门搞这一块的,也没有经过测试,只是我一时突发奇想,如果有什么不对的地方也请大家不要建议,也希望大家能够多多讨论。
还有一些人问我,那不如直接全部用udp不是更简单,针对这一点我想说的是,udp是不确定内容完整性的。及时通信一般传输的都是字符流,我们很难确保发出去的包都能收到,而且接收的顺序不确定性(当然也有一些扩展协议能够补充这一点),所以发送消息不如直接用tcp协议,这样可以确保服务器能够收到而且也省了很多麻烦。
当然这个想法应该不是我第一个想到的,也许已经有一些公司尝试过了,或者已经有成熟的产品在运用,还是请大家多多拍砖呵呵。