1、引言
经验过稍有些规模的IM零碎开发的同行们都有领会,要想实现大规模并发IM(比方亿级用户和数十亿日音讯量这样的规模),在架构设计上须要一些额定的思考,尤其是要解决用户高并发、服务高可用,架构和实现细节上都须要不短时间的打磨。
我在过往的工作经验里,亲手设计和实现了一套亿级用户量的IM,平台上线并通过6年多的验证,稳定性和可用性被验证齐全达到预期。
这套IM零碎,从上线至今已6年无余,自己也曾经到职守业近2年,但当初设计和开发这套零碎时积攒和播种了大量的第一手实践经验和技术心得。
因而,想借本文把过后的架构设计经验记录下来,作为同行交换和参考,心愿能提供一些启发,少走弯路。
本文已同步公布于“即时通讯技术圈”公众号,欢送关注。公众号上的链接是:点此进入。
2、系列文章
为了更好以进行内容出现,本文拆分两了高低两篇。
本文是2篇文章中的第1篇:
《一套亿级用户的IM架构技术干货(上篇):整体架构、服务拆分等》(本文)
《一套亿级用户的IM架构技术干货(下篇):可靠性、有序性、弱网优化等(稍后公布...)》
本篇次要总结和分享这套IM架构的总体设计和服务拆分等。
3、原作者
本文基于邓昀泽的“大规模并发IM服务架构设计”一文进行的扩大和订正,感激原作者的分享。
邓昀泽:毕业于北京航空航天大学,现蓝猫微会创始人兼CEO,曾就任于美团、YY语音、微软和金山软件等公司,有十多年研发治理教训。
4、技术指标
在这套IM零碎的架构上,技术上咱们保持高要求,通过数年的验证,也的确达到了设计预期。
这4大技术指标是:
具体解释就是:
- 1)高牢靠:确保不丢音讯;
- 2)高可用:任意机房或者服务器挂掉,不影响服务;
- 3)实时性:不论用户在哪里,在线用户音讯在1秒内达到(咱们理论是75%音讯能够做到120ms);
- 4)有序性:确保用户音讯的有序性,不会呈现发送和承受的乱序。
5、架构拆分
从整体架构上来说,亿级用户量的IM架构整体上偏简单。
传统开源的IM服务喜爱把所有服务做到1-2个服务里(Connector+Service模型),这样带来的问题比较严重。
传统开源的IM的问题次要体现在:
- 1)服务代码简单,难以继续开发和运维;
- 2)繁多业务逻辑出问题,可能会影响到其它逻辑,导致服务的全面不可用。
因而,我在做架构设计的时候尽量谋求微服务化。即把整体架构进行分拆为子系统,而后子系统内依照业务逻辑分拆为微服务。
零碎拆分如下图:
4个子系统的职责是:
- 1)IM业务零碎:服务IM相干的业务逻辑(比方好友关系、群关系、用户信息等);
- 2)信令零碎:负责用户登录,用户在线状态的保护,以及在线用户的上行推送;
- 3)推送零碎:负责音讯的在线推送和离线推送;
- 4)存储系统:负责音讯和文件的存储和查问;
其中:信令零碎和推送零碎是基础设施,不只是能够为IM业务服务,也能够承载其它相似的业务逻辑(比方客服零碎)。
在部署层面:采纳存储3外围机房,信令和推送节点按需部署的形式(国内业务举荐8-10个点)。实际上咱们只做了了北京3个机房,上海1个机房和香港一个机房的部署,就基本上满足了大陆+香港的业务需要。
上面将一一介绍这4个子系统的细节方面。
6、IM业务零碎
一说到IM,很多人脑海里跳出的第一个要害就是“即时通信”,技术上天经地义的联想到了socket,也就是大家成天嘴上说的:“长连贯”。换句话说,很多对IM不理解或理解的不多的人,认为IM里的所有数据交互、业务往来都是通过“长连贯”来实现的,这样话,对于本文章中拆分出的“IM业务零碎”就有点不了解了。
实际上,晚期的IM(比方20年前的QQ、MSN、ICQ),的确所有数据根本都是通过“长连贯”(也就是程序员所说的“socket”)实现。
但现在,挪动端为主端的IM时代,IM零碎再也不是一个条“长连贯”走天下。
当初,一个典型的IM零碎数据往来通常拆分成两种服务:
- 1)socket长连贯服务(也就是本文中的“推送服务”);
- 2)http短连贯服务(就是最罕用的http rest接口那些,也就是本文中的“IM业务零碎”)。
艰深一点,也也就当初的IM零碎,通常都是长、短连贯配合一起实现的。
比方论坛里很多热门技术计划都是这样来做的,比方最典型的这两篇:《IM单聊和群聊中的在线状态同步应该用“推”还是“拉”?》、《IM音讯送达保障机制实现(二):保障离线音讯的牢靠投递》,文记里提到的“推”其实就是走的“长连贯”、“拉”就上指的http短连贯。
对于socket长连贯服务就没什么好说,就是大家最常了解的那样。
IM业务零碎具体来说,就是专一解决IM相干的业务逻辑,比方:
- 1)保护用户数据:用户根本信息等;
- 2)保护好友关系:好友申请、好友列表、好友信息等;
- 3)保护群组信息:群创立、遣散、成员治理等;
- 4)提供数据:离线拉取、历史记录同步;
- 5)其它逻辑:比方通过存储和推送零碎,存储音讯和发送告诉;
依照微服务的准则,IM业务零碎也被分拆为多个服务,比方:
- 1)GInfo服务:群组信息保护;
- 2)IM服务:解决1V1音讯;
- 3)GIM服务:解决群组音讯。
7、信令零碎
7.1 根本状况
信令零碎主要职责是3局部:
1)保护用户在线状态:
因为用户规模宏大,必然是多个集群,每个集群多台服务器为用户提供服务。
思考到服务器运维的复杂性,咱们要假设任何一个集群,任何一个服务器都可能会挂掉,而且在这种状况下要可能持续为用户提供服务。
在这种状况下,如果用户A给用户B发消息,咱们须要晓得用户B在哪个服务器上,能力把音讯正确推送给用户B。用户在哪个信令服务,这个信息就是在线状态数据。
2)上行音讯推送:
跟上一个职责无关,用户在线的时候,如果有其它用户给他发消息,那就最好不要走离线推送,而是走在线推送。
在线推送的最初一个环节,是把用户音讯推送给用户设施,因为就须要晓得用户登录到哪个服务器上。
3)业务散发:
信令服务不只能够解决IM申请,也能够解决其它类型的业务申请。为了解决不同的业务,就须要有散发能力。
具体做法是通过一个SVID(service id)来实现,不同的业务携带不同的SVID,信令服务就晓得如何散发了。
用户通过登录服务把数据(比方IM音讯)发送到信令零碎,信令零碎依据SVID转发给IM零碎。不论后盾有多少个业务,用户只须要一条链接到信令。
7.2 服务拆分
信令零碎为了实现以上这3个职责,同时要确保咱们服务可平行扩大的能力和稳定性,在理论的技术实现上,咱们实际上把信令服务分拆为3个服务模块。
如下图所示:
上面将一一介绍这3个子服务。
7.3 Login服务
Login服务次要负责保护用户长链接:
- 1)每个用户一条链接到Login服务,并按工夫发心跳包给Login服务;
- 2)服务定时检查用户链接状态和心跳包,比方发现2个心跳周期都没收到心跳,就认为用户掉线了(有假在线问题,有趣味同学可回贴探讨)。
Login服务收到用户登录申请当前,验证uid/cookie,如果胜利就把这个用户的登录信息发送给online。
此过程次要记录的信息蕴含:
- 1)uid(用户id);
- 2)Login服务器IP/Port;
- 3)Route服务器的IP/Port。
如果用户发送IM音讯,先发送到Login,Login转发给Route,Route依据服务的类型(SVID),发现是IM协定就发送给后端的IM服务。
Login对并发要求比拟高,个别要反对TCP+UDP+Websocket几种形式,单服务能够做到10-250万之间。从服务稳定性角度触发,倡议是管制VM的CPU/内存,单服务器以20-50万为适合。
Login服务器自身没有状态,任何一个Login服务断掉,用户端检测到当前重连另一个Login服务器就能够了,对整体服务可靠性根本没有影响。
7.4 Online服务
Online服务次要负责保护用户的在线信息:
- 1)如果用户掉线,Online服务里信息就是空;
- 2)如果用户在线,Online就能找到用户登录在哪个集群,哪个Login服务器上。
Online业务绝对简略:多个Login服务器会连贯到Online,定期同步用户登录和离线信息。
Online主要职责是:把用户状态信息存储在Redis集群里。因而也是无状态的,任何一个Online服务挂掉,不影响整体服务能力。
如果集群规模不大,用户规模也不大,Online服务也能够收到Login服务里去。
如果规模比拟大,倡议分拆进去,一方面简化Login的逻辑复杂度,同时防止写Redis的慢操作放在Login服务里。因为Login要同时解决50万以上的并发链接,不适宜在循环里嵌入慢操作。
7.5 Route服务
Route服务的设计外围,是作为信令零碎跟其它子系统的交互层。Route下接Login服务,能够承受用户业务信息(IM),也能够往用户推送上行音讯。
多个后端业务零碎能够接入到Route,依照服务类型(SVID, service id)注册。比方IM服务能够接入到Route, 注册SVID_IM。这样Login接管到SVID=SVID_IM的音讯,转发给Route,Route就能够依据SVID转发给IM相干的服务。
Route简略的依据SVID做转发,不解决具体的业务逻辑,因而也是无状态的。一个信令集群能够有多个Route服务,任何服务挂了不影响整体服务能力。
8、推送零碎
推送零碎的外围工作:是接管到给用户发送上行音讯的申请当前,去信令服务查问用户是否在线,如果在线走信令推送,如果不在线走离线推送(如iOS的APNS、华为推送、小米推送等)。
因为推送服务可能呈现大规模并发簇拥,比方大群强烈探讨的时候,会触发亿级的TPS。因而推送服务用Kafka做了削峰。
我在理论的技术实现上,将推送零碎进行了如下细分:
具体就是:
- 1)PushProxy:承受用户的推送申请,写入Kafka;
- 2)Kafka:缓存推送服务;
- 3)PushServer:从Kafka获取推送申请,判断用户是否在线;
- 4)PushWorker:真正推送给信令或者APNS,华为推送等。
这里同样,除了Kafka以外每个服务都是无状态的,因为也能够实现平行扩大和容错,任何服务挂掉不影响整体服务可用性。
9、存储系统
存储服务次要是负责音讯的存储和查问,因为音讯量微小,对存储服务的并发能力和存储量要求微小。
为了均衡性能、空间和老本,存储服务按数据的热度进行了分级和区别对待。
具体是:
- 1)短期音讯(7天):存储在Redis里;
- 2)近期音讯(1-3个月):存储在Mysql里,以备用户实时查问;
- 3)历史信息:存储在HBase里,作为历史数据慢查问。
同时,为了应答超大群的大量音讯解决,存储服务在理论的技术实现上,也做了比拟细的分拆。
存储服务具体拆分如下图:
具体的业务划分就是:
- 1)MsgProxy:负责承受IM子系统的存储申请,写入Kafka;
- 2)MsgWriter:从Kafka获取写申请,按需写入Redis和Mysql;
- 3)MsgReader:承受用户的音讯查问申请,从Redis,Mysql或者HBase读数据;
- 4)运维工具:次要是数据库的运维需要。
音讯队列(Kafka)在这里角色比拟重要,因为对于高并发申请(100万人公众号),须要通过音讯队列来做削峰和并行。
在具体部署上:可能是3-4个MsgProxy,后端能够对应15个左右的MsgWriter。MsgWriter是比较慢的,须要同时操作多个数据库,还要保障操作的原子性。
10、本篇小结
本篇次要总结了这套亿级用户量IM零碎的总体架构设计,为了高性能和横向扩展性,基于微信的理念将整个架构在实现上分成了4个子系统,别离是:IM业务零碎、信令零碎、推送零碎、存储系统。
针对这4个子系统,在理论的技术应用层上,又进行了进一步的服务拆分和细化,使得整个架构伸缩性大大加强。
—— 下篇《一套亿级用户的IM架构技术干货(下篇):可靠性、有序性、弱网优化等》稍后公布,敬请期待 ——
附录:相干文章
《浅谈IM零碎的架构设计》
《简述挪动端IM开发的那些坑:架构设计、通信协议和客户端》
《一套海量在线用户的挪动端IM架构设计实际分享(含具体图文)》(* 力荐)
《一套原创分布式即时通讯(IM)零碎实践架构计划》(* 力荐)
《从零到卓越:京东客服即时通讯零碎的技术架构演进历程》(* 力荐)
《蘑菇街即时通讯/IM服务器开发之架构抉择》
《腾讯QQ1.4亿在线用户的技术挑战和架构演进之路PPT》
《微信后盾基于工夫序的海量数据冷热分级架构设计实际》
《挪动端IM中大规模群音讯的推送如何保障效率、实时性?》
《古代IM零碎中聊天音讯的同步和存储计划探讨》(* 力荐)
《以微博类利用场景为例,总结海量社交零碎的架构设计步骤》
《一套高可用、易伸缩、高并发的IM群聊、单聊架构方案设计实际》(* 力荐)
《社交软件红包技术解密(一):全面解密QQ红包技术计划——架构、技术实现等》
《社交软件红包技术解密(二):解密微信摇一摇红包从0到1的技术演进》
《社交软件红包技术解密(三):微信摇一摇红包雨背地的技术细节》
《社交软件红包技术解密(四):微信红包零碎是如何应答高并发的》
《社交软件红包技术解密(五):微信红包零碎是如何实现高可用性的》
《社交软件红包技术解密(六):微信红包零碎的存储层架构演进实际》
《社交软件红包技术解密(七):支付宝红包的海量高并发技术实际》
《社交软件红包技术解密(八):全面解密微博红包技术计划》
《从游击队到正规军(一):马蜂窝旅游网的IM零碎架构演进之路》(* 力荐)
《从游击队到正规军(二):马蜂窝旅游网的IM客户端架构演进和实际总结》
《从游击队到正规军(三):基于Go的马蜂窝旅游网分布式IM零碎技术实际》
《瓜子IM智能客服零碎的数据架构设计(整顿自现场演讲,有配套PPT)》
《阿里钉钉技术分享:企业级IM王者——钉钉在后端架构上的过人之处》
《微信后盾基于工夫序的新一代海量数据存储架构的设计实际》
《一套亿级用户的IM架构技术干货(上篇):整体架构、服务拆分等》更多同类文章 ……
本文已同步公布于“即时通讯技术圈”公众号。
▲ 本文在公众号上的链接是:点此进入。同步公布链接是:http://www.52im.net/thread-3393-1-1.html