大家工作生活中可能经常使用微信、钉钉这样的即时通讯工具,作为技术开发的你有没有想过它们后端的技术架构是如何做的?
一般来说,钉钉和微信后端主要就是一个IM的即时通讯软件,再加上很多周边功能,我们先来看下IM这块的核心功能包含哪些模块:
0)用户:系统的使用者。
1)消息:是指用户之间的沟通内容(通常在IM系统中,消息会有以下几类:文本消息、表情消息、图片消息、视频消息、文件消息等等)。
2)会话:通常指两个用户之间因聊天而建立起的关联。
3)群:通常指多个用户之间因聊天而建立起的关联。
4)终端:指用户使用IM系统的机器(通常有Android端、iOS端、Web端等等)。
5)未读数:指用户还没读的消息数量。
6)用户状态:指用户当前是在线、离线还是挂起等状态。
7)关系链:是指用户与用户之间的关系,通常有单向的好友关系、双向的好友关系、关注关系等等(这里需要注意与会话的区别:用户只有在发起聊天时才产生会话,但关系并不需要聊天才能建立。对于关系链的存储,可以使用图数据库(Neo4j等等),可以很自然地表达现实世界中的关系,易于建模)。
8)单聊:一对一聊天。
9)群聊:多人聊天。
10)客服:在电商领域,通常需要对用户提供售前咨询、售后咨询等服务(这时,就需要引入客服来处理用户的咨询)。
11)消息分流:在电商领域,一个店铺通常会有多个客服,此时决定用户的咨询由哪个客服来处理就是消息分流(通常消息分流会根据一系列规则来确定消息会分流给哪个客服,例如客服是否在线(客服不在线的话需要重新分流给另一个客服)、该消息是售前咨询还是售后咨询、当前客服的繁忙程度等等)。
12)信箱:本文的信箱我们指一个Timeline、一个收发消息的队列。
涉及到功能的具体实现还有很多概念需要先了解下
读扩散 vs 写扩散
IM系统里经常会涉及到读扩散和写扩散这两个技术概念,我们来看看。
读扩散
如上图所示:A与每个聊天的人跟群都有一个信箱(有些地方会叫Timeline),A在查看聊天信息的时候需要读取所有有新消息的信箱。
需要注意与Feeds系统的区别:在Feeds系统中,每个人都有一个写信箱,写只需要往自己的写信箱里写一次就好了,读需要从所有关注的人的写信箱里读。但IM系统里的读扩散通常是每两个相关联的人就有一个信箱,或者每个群一个信箱。
读扩散的优点:
1)写操作(发消息)很轻量,不管是单聊还是群聊,只需要往相应的信箱写一次就好了;
2)每一个信箱天然就是两个人的聊天记录,可以方便查看聊天记录跟进行聊天记录的搜索。
读扩散的缺点:读操作(读消息)很重,在复杂业务下,一条读扩散消息源需要复杂的逻辑才能扩散成目标消息。
写扩散
接下来看看写扩散。
如上图所示:在写扩散中,每个人都只从自己的信箱里读取消息。
但写(发消息)的时候,对于单聊跟群聊处理如下:
1)单聊:往自己的信箱跟对方的信箱都写一份消息,同时,如果需要查看两个人的聊天历史记录的话还需要再写一份(当然,如果从个人信箱也能回溯出两个人的所有聊天记录,但这样效率会很低);
2)群聊:需要往所有的群成员的信箱都写一份消息,同时,如果需要查看群的聊天历史记录的话还需要再写一份。可以看出,写扩散对于群聊来说大大地放大了写操作。
PS:实际上群聊中消息扩散是IM开发中的技术痛点,有兴趣建议详细阅读:《有关IM群聊技术实现的文章汇总》。
写扩散优点:
1)读操作很轻量;
2)可以很方便地做消息的多终端同步。
写扩散缺点:写操作很重,尤其是对于群聊来说(因为如果群成员很多的话,1条消息源要扩散写成“成员数-1”条目标消息,这是很恐怖的)。
由于概念比较多,一篇文章是不可能全部描述清楚的,还有像钉钉,微信这种亿级海量用户的系统架构实现难度是非常大的,随便给你说几个架构难点,看下你自己是否知道!
架构难点
1、亿级用户同时在线聊天如何保证高并发聊天消息正常推送
2、公众号千万级粉丝大V发文章如何让粉丝高效收取
3、高并发聊天系统如何保证发送的消息不乱序
4、微信钉钉后端海量离线消息如何高效存储与获取
5、高并发聊天系统如何保证发送的消息不丢失
6、单聊与群聊数据收发机制用读扩散还是写扩散
7、微信后端PB级海量历史聊天消息数据如何存储
8、应该如何架构微信春晚抢红包高并发系统
9、微信钉钉后端如何保证消息收发核心链路高可用
10、微信钉钉的群聊为什么要设置人数上限
11、如何架构微信后端百万在线直播互动系统
12、如何设计微信钉钉后端系统的缓存架构抗高并发
13、微信朋友圈日均千亿访问量背后会有哪些技术挑战
看完懵了么?再继续看下图,给大家写了一套亿级钉钉微信后端IM架构核心(1.0)的图,感觉怎么样?
是不是觉得以上架构难点都不一定遇得上?下面这十几道关于Netty以及微信钉钉架构的题,都是2021年大厂的热门题,来看看你会几道?
一线大厂面试题
1、BIO、NIO和AIO模型的区别
2、同步与异步、阻塞与非阻塞的区别
3、select、poll、epoll的机制及其区别
4、Netty底层操作与Java NIO操作对应关系如何
5、Netty的线程模型是怎样的,与Redis线程模型有区别吗
6、说说Reactor响应式编程是怎么回事
7、Netty的粘包/拆包是怎么处理的,有哪些实现
8、Netty的protobuf编解码机制是怎样的
9、Netty如何实现断线自动重连
10、Netty如何支持单机百万连接
11、说下Netty零拷贝的原理
12、说下Netty如何实现长连接心跳保活机制
13、Netty的内存池是怎么实现的
14、Netty是如何解决NIO底层epoll空轮询导致CPU 100%的Bug
15、Netty高并发高性能体现在哪些方面
16、基于Netty如何设计微信钉钉后端高并发IM架构
17、大规模Netty服务集群应该如何架构
18、基于Netty推送消息如何保证不丢消息
19、为什么微信钉钉的群人数要设上限
20、微信钉钉后端PB级海量消息如何存储
据我所知,如果能回答出其中的一半,就算是勉强及格了。
如果这些你都能全部回答出来,那你应该是妥妥的技术大牛了!可以放心去投大厂简历了!