背景:除去大名鼎鼎的QQ这款即时聊天工具,还有许多细分行业的IM,好比淘宝阿里旺旺、网易泡泡、YY语音......。恰巧公司产品也要开发一款基于咱们本身行业的类IM系统,颇有幸我担当了这个产品的架构师,核心代码编写、实现者。下面我近年来从技术上我对IM系统(即时消息的传输,不包括语音,视频,文件的传输)的理解和设计分享出来,浅薄之见,望你们别见笑,欢迎给出批评意见。web
目前我知晓的全部IM系统传输即时消息无外乎使用UDP、TCP、基于TCP的http这几种协议中的一种或几种。好比QQ主要采用UDP协议,MSN主要采用TCP协议,并且他们也都支持HTTP协议的代理模式。更多资料,请参加这篇文章《一些经常使用软件的网络端口协议分类介绍》。数据库
咱们该如何选择呢?缓存
UDP协议实时性更好,可是如何处理安全可靠的传输而且处理不一样客户端之间的消息交互是个难题,实现起来过于复杂;安全
HTTP协议属于扩展支持,咱们在产品的初始阶段能够不用支持;服务器
那就非TCP协议莫属了,要考虑的一样也有不少,特别是若是有海量用户的需求。如何保证单机服务器高并发量,如何作到灵活,扩展的架构。微信
Tips: QQ 为何采用 UDP 协议,而不采用 TCP 协议实现?网络
二进制格式?文本格式?这个话题转到个人这篇文章《网络传输数据格式的选择》,从咱们当前的需求和产品周期上我以为选择JSON形式的数据协议是最好的。session
首先咱们来提炼一下一个IM系统的主要需求,包括帐号,关系链,在线状态显示,消息交互......。架构
架构考量:并发
因为采用可靠传输协议TCP,考虑到负载问题(短链接实现帐号、关系链相关业务,长链接实现上线、信息推送);
后台架构的灵活性、可扩展性,支持分布式部署——把网络层、业务逻辑层、数据层分离,网络层和业务层支持负载均衡策略、数据层支持分布式存储;
客户端SDK的易用性:把网络层、数据层分离、业务逻辑层分离;
后台架构简化图
架构示意图
架构细化图
说明
从<架构细化图>中能够看出对于上线服务因为创建的是TCP长链接,对于单台服务器每每因为硬件资源、系统资源、网络资源的限制没法作到海量用户的同时在线,因此设计为根据服务器负载支持多服务器上线,同时因为多服务器上线形成了对整个系统交互(不一样的客户端的交互,协做部门应用服务和客户的交互)的分割,引入消息转发服务器做为粘合点。另外对于多服务器上线形成的统一帐户信息(在线状态,消息)数据的分割,引入统一的数据层(内存存储层:session、状态信息存储、消息队列存储;数据库:帐号信息存储)作到业务和数据的分离,也就作到了支持分布式部署。参见个人这篇文章《构建高性能服务的考量》
对于部分业务服务:作到网络层、业务层、数据层的彻底分离。首先对于TCP短链接来讲不会如长链接那般消耗资源,即便后期遇到海量的并发访问请求依然能够从容的经过负载均衡策略和数据分布式部署策略进行解决。参见个人这篇文章《服务端架构中的“网关服务器”》
服务端平台及技术选型
系统开发平台: CentOS——Linux发行版的一种,稳定可靠、可定制优化、支持丰富;
网络支撑层: libevent——减少开发成本,加强稳定性;
缓存存储层: Redis——支持丰富的存储结构,支持分布式存储;
数据库: MySQL——最适合互联网的数据库,免受权、高效稳定、可控性高;
开发语言: C/C++;
部分热点问题考量
系统性能考量:
编码角度:采用高效的网络模型,线程模型,I/O处理模型,合理的数据库设计和操做语句的优化;
垂直扩展:经过提升单服务器的硬件资源或者网络资源来提升性能;
水平扩展:经过合理的架构设计和运维方面的负载均衡策略将负载分担,有效提升性能;后期甚至能够考虑加入数据缓存层,突破IO瓶颈;
系统的高可用性:(防止单点故障)
在架构设计时作到业务处理和数据的分离,从而依赖分布式的部署使得在单点故障时能保证系统可用。
对于关键独立节点能够采用双机热备技术进行切换。
数据库数据的安全性能够经过磁盘阵列的冗余配置和主备数据库来解决。
Tips:若是要支持web IM,请阅读《Web推送技术研究》
主要学习资料: 请自行google。
《1.4亿在线背后的故事》;
《BasicDB的架构演变》;
《微信之道-至简》;