本文由转转王棕生分享,原题“IM系列(一):转转IM系统架构探秘”,下文进行了排版和内容优化。
1、引言
转转是二手电商平台,在这个平台上,人人可以是买家,人人也可以是卖家。转转从最初的信息模式升级为一个闭环的交易模式,IM打通了买家与卖家之间的通道。本文描述了转转IM为整个平台提供的支撑能力,给出了系统的整体架构设计,分析了系统架构的特性。
2、系列文章
本文是系列文章中的第1篇,本系列文章的大纲如下:
3、本文作者
王棕生:转转架构平台部高级研发工程师,负责IM系统、推送系统和分布式存储系统。
4、系统能力定义
转转IM需要提供如下的支撑能力:
1)有的用户习惯使用APP、有的用户习惯免安装的小程序;还有的用户习惯于在“58同城”APP上搜索二手;所以IM需要支持APP、小程序、M端等各种终端类型,以及由转转平台衍生出的其他垂类APP。
2)IM是转转平台中的一个独立系统,需要向平台中的其他系统(如客服系统、风控系统)提供“联系人”和“私信”等IM能力。
3)在转转平台的各种运营活动中,需要借助于IM通道将商品消息、订单消息、交易消息及活动通知等实时的发送给用户。
总之:IM为转转平台提供一个可靠和稳定的通道,为用户与用户之间、业务系统与用户之间、平台与用户之间打造一个可以即时通讯的环境。
5、系统架构概览
转转IM系统架构设计如下图所示,自上而下包括四层:用户层、入口层、逻辑层和原子存储层。
转转IM系统架构设计图:
6、系统架构之“用户层”
用户层是IM服务的调用者,用户层支撑各类业务应用,包括APP、小程序、M端、平台运营类业务系统和ZZRPC。
APP基于TCP协议与IM服务端进行消息传输,小程序和M端则是通过HTTP协议。
ZZRPC是转转平台使用Java语言自研的RPC框架,而转转IM系统是使用C++语言进行研发的,所以IM需要通过适配支持ZZRPC服务的相互调用。
7、系统架构之“入口层”
入口层是IM系统的入口网关,包括:
- 1)Entry
- 2)Http-Entry
- 3)转转自研的分布式消息中间件ZZMQ;
- 4)IMUI。
Entry:负责维护与APP之间的TCP连接,把APP发送的业务请求包向后直接转发到逻辑层进行处理。Entry逻辑较为简单,不参与具体的业务处理,这样设计的原因是为了避免Entry因业务改造升级进行模块重启,而丢失与APP之间的TCP连接,影响大量用户。
Http-Entry:是HTTP版的Entry实现,Http-Entry负责维护的是与小程序和M端之间通过HTTP协议模拟的“长连接”。
HTTP“长连接”的实现原理是:小程序发送http_request到Http-Entry,Http-Entry会hold住连接不返回、不释放;当产生了该用户的私信数据时或hold住连接超过一定时间(如15秒)时,Http-Entry则返回http_response到小程序;小程序收到http_response时需要立即再次发送http_request到Http-Entry......。
ZZMQ:是转转自研的分布式消息队列,接收平台各个运营类业务系统生产的系统消息、广播消息和推送类消息,然后由IM逻辑模块进行消费处理。ZZMQ解耦了平台业务系统和IM系统。
IMUI:用于IM系统适配ZZRPC的调用;IMUI作为ZZRPC服务的提供者,接收ZZRPC客户端的请求后,按照IM系统的内部协议格式同步访问逻辑层,再将逻辑层的操作结果按ZZRPC协议进行封装,然后返回到ZZRPC的客户端。
8、系统架构之“逻辑层”
逻辑层包括Logic和Extlogic两个模块组件:
- 1)Logic负责实现IM系统核心的和轻量级的业务逻辑,如用户登录、获取未读数、发送私信等;
- 2)非核心的和重量级的业务由Extlogic进行实现;
- 3)Logic和Extlogic两个逻辑模块通过ZZMQ进行解耦。
例如:在私信逻辑处理流程中,Logic接收私信和用户在线时的私信推送,而对于离线私信Logic则会通过ZZMQ通知Extlogic进行离线消息的召回逻辑处理。
9、系统架构之“原子存储层”
IM需要持久化存储的数据包括私信消息、系统消息和联系人等。
这些数据通过传统的关系型数据库MySQL和NewSQL数据库TiDB进行保存:
- 1)TiDB是分布式数据库,具有天然的弹性扩容特性;
- 2)MySQL通过通用的分库分表策略来应对存储和查询负载。
Das接收逻辑层对持久化数据的读写请求,将请求放入本地队列中,然后按顺序对数据库进行同步读写操作。
ZZRedis是转转自研的分布式缓存系统,负责对用户的在线信息进行缓存。
Jtransit与IMUI类似,用于适配ZZRPC服务;Jtransit作为ZZRPC服务的调用,接收逻辑层的请求后,按照ZZRPC协议格式访问平台其他系统提供的服务,获取数据后封装成IM系统的协议数据返回到逻辑层。
10、架构特性1:伸缩性
对转转IM系统架构设计,从伸缩性、高可用、可靠性、可扩展性和高性能分别进行分析。
当转转并发访问的用户量不断增加,IM系统资源紧张时,需要通过增加机器进行水平弹性扩容,主要是通过服务管理平台控制中心进行实施的。入口层、逻辑层和原子层服务之间相互调用的关系如下表所示。
Entry和Http-Entry会作为调用方调用Logic的服务,Logic和Extlogic会作为调用方调用Das的服务和Entry与Http-Entry的服务,这些服务之间的关系通过控制中心进行管理。
首先:
- 1)服务方组件与控制中心建立TCP长连接,将服务内容包括本实例ip、端口、服务接口等等注册到控制中心;
- 2)调用方组件与控制中心建立TCP长连接,从控制中心轮询服务列表;
- 3)服务方组件增加机器弹性扩容时,新的实例会注册到控制中心,进而被调用方实时拉取到。
另外:
- 1)App通过域名连接Entry时会首先访问TGW,由TGW转发请求到Entry,所以增加Entry实例时需要在TGW进行注册;
- 2)小程序到Http-Entry的HTTP请求都是由Nginx进行中转,所以增加Http-Entry机器需要在Nginx上进行配置;
- 3)Extlogic作为ZZMQ的消费者,可以自由增加实例。
存储层扩容:
- 1)数据库MySQL通过分库和分表的方式进行扩容;
- 2)分布式数据库TiDB以及分布式缓存ZZRedis;
- 3)还有分布式消息队列ZZMQ自身具有天然的弹性伸缩特性。
11、架构特性2:高可用
1)入口层高可用:入口层Entry和Http-Entry的可用性分别由TGW和Nginx进行探活和迁移。
2)Logic高可用:Logic的可用性由入口层实例进行控制;为了保证同一用户消息的顺序性,Entry和Http-Entry会将同一个用户的请求通过哈希算法打到相同的Logic实例;若一索引号为x的Logic实例挂掉以后,Entry和Http-Entry会在重试后将请求打到索引号为(x+p)%n的Logic实例上(n为Logic实例数目,p的取值区间为[1,n) );注意p的取值不能固定,否则很容易将瞬时流量打到固定的Logic实例,引起雪崩效应。
3)Extlogic高可用:Extlogic负责消费消息队列ZZMQ中的消息,挂掉任意一个实例后,不影响业务的正常处理。
4)Das高可用:Das的高可用由Logic和Extlogic进行控制,原理与Logic高可用一致,在挂掉任意一个Das实例后,Logic和Extlogic会将请求打到索引号为(x+p)%n的Das实例上。
5)存储层高可用:MySQL通过一主两备模式保证其高可用,在主库挂掉以后,其中的一个备库变为主库继续对Das提供服务;分布式数据库TiDB、分布式缓存ZZRedis,分布式消息队列ZZMQ自身具有天然的高可用特性。
12、架构特性3:可靠性
程序的正确处理保证系统的可靠性,影响IM系统可靠性的因素主要是瞬时高峰导致的逻辑层Logic实例的系统资源被用光和原子层Das对数据库的访问超时。
1)Logic可靠性:逻辑层实例的系统资源被用光发生在业务的相互影响;例如瞬时大量用户登录IM系统时,Logic大部分或全部线程被调度用于处理用户登录业务,而没有足够的资源去处理私信等业务。提高Logic可靠性的方案,可以根据微服务思想对Logic按功能职责进行拆分,如拆分成Login_Logic、Msg_Logic、Contact_Logic等。
2)Das可靠性:对数据库的访问超时发生在数据库负载较高时,例如推送千万级广播系统消息时,会有大量的更新操作落到数据库上,此时数据库响应较慢或超时;因为Das对数据库的操作是同步的,所以会造成Das内部队列请求的堆积,其他业务请求也会被堆积而导致超时。提高Das可靠性的方案,可以根据业务类型在Das内部分别创建不同的请求队列,从而避免业务的相互影响。
13、架构特性4:可扩展性和高性能
1)可扩展性:转转IM系统架构的可扩展性体现在逻辑层,逻辑层Logic和Extlogic通过消息队列ZZMQ进行解耦,定制类的功能需求在Extlogic中进行实现,避免对核心业务Logic的影响。
ZZMQ除了解耦Logic和Extlogic外,还对平台的业务系统和IM系统进行解耦。
2)高性能:分析IM系统架构,入口层和逻辑层主要是计算模块,原子存储层主要是IO模块,系统的性能瓶颈集中在数据库端。提升性能方案有:通过增强机器配置、增加机器、研究和新的存储方式,如用户联系人可以通过KList引擎进行存储。
14、本文小结
转转IM为用户与用户之间、客服与用户之间、平台与用户之间打造了一个高效和可靠的通讯通道。
按微服务私信和分层模式对IM系统架构进行分布式设计,架构中每个组件模块的功能职责明确。
具体的功能职责如下:
- 1)Entry负责维护TCP连接;
- 2)Http-Entry负责维护HTTP连接;
- 3)Logic负责处理核心的轻量级业务,Logic要求服务稳定;
- 4)Extlogic负责处理非核心的重量级业务,Extlogic要求服务可扩展;
- 5)Das负责对数据库进行读写访问;
- 6)IMUI和Jtransit负责对平台的RPC框架ZZRPC进行适配;
- 7)MySQL、TiDB和ZZRedis负责持久化和缓存数据;
- 8)ZZMQ负责对平台的业务系统和IM系统,以及Logic和Extlogic之间进行解耦。
转转IM的系统架构具有伸缩性、高可用、可靠性、功能扩展性和高性能。
15、参考资料
[1] 浅谈IM系统的架构设计
[2] 简述移动端IM开发的那些坑:架构设计、通信协议和客户端
[3] 一套海量在线用户的移动端IM架构设计实践分享(含详细图文)
[4] 一套原创分布式即时通讯(IM)系统理论架构方案
[5] 从零到卓越:京东客服即时通讯系统的技术架构演进历程
[6] 蘑菇街即时通讯/IM服务器开发之架构选择
[7] 现代IM系统中聊天消息的同步和存储方案探讨
[8] 一套高可用、易伸缩、高并发的IM群聊、单聊架构方案设计实践
[9] 马蜂窝旅游网的IM系统架构演进之路
[10] 瓜子IM智能客服系统的数据架构设计(整理自现场演讲,有配套PPT)
[11] 阿里钉钉技术分享:企业级IM王者——钉钉在后端架构上的过人之处
[12] 一套亿级用户的IM架构技术干货(上篇):整体架构、服务拆分等
[13] 从新手到专家:如何设计一套亿级消息量的分布式IM系统
[14] 闲鱼亿级IM消息系统的架构演进之路
[15] 基于实践:一套百万消息量小规模IM系统技术要点总结
[16] 一套十万级TPS的IM综合消息系统的架构实践与思考
[17] vivo直播系统中IM消息模块的架构实践
[18] 一套分布式IM即时通讯系统的技术选型和架构设计
[19] 微信团队分享:来看看微信十年前的IM消息收发架构,你做到了吗
[20] 携程技术分享:亿级流量的办公IM及开放平台技术实践
(本文已同步发布于:http://www.52im.net/thread-4764-1-1.html)