大神级项目!300分钟撸一个基于高并发Netty的NIO框架
共 3107字,需浏览 7分钟
·
2021-09-18 14:19
大家工作生活中可能经常使用微信、钉钉、微博这样的软件,作为技术开发的你有没有想过它们后端的技术架构是如何做的?
IM核心功能
一般来说,钉钉和微信后端主要就是一个IM的即时通讯软件,再加上很多周边功能,我们先来看下IM这块的核心功能包含哪些模块:
0)用户:系统的使用者。
1)消息:是指用户之间的沟通内容(通常在IM系统中,消息会有以下几类:文本消息、表情消息、图片消息、视频消息、文件消息等等)。
2)会话:通常指两个用户之间因聊天而建立起的关联。
3)群:通常指多个用户之间因聊天而建立起的关联。
4)终端:指用户使用IM系统的机器(通常有Android端、iOS端、Web端等等)。
5)未读数:指用户还没读的消息数量。
6)用户状态:指用户当前是在线、离线还是挂起等状态。
7)关系链:是指用户与用户之间的关系,通常有单向的好友关系、双向的好友关系、关注关系等等(这里需要注意与会话的区别:用户只有在发起聊天时才产生会话,但关系并不需要聊天才能建立。对于关系链的存储,可以使用图数据库(Neo4j等等),可以很自然地表达现实世界中的关系,易于建模)。
8)单聊:一对一聊天。
9)群聊:多人聊天。
10)客服:在电商领域,通常需要对用户提供售前咨询、售后咨询等服务(这时,就需要引入客服来处理用户的咨询)。
11)消息分流:在电商领域,一个店铺通常会有多个客服,此时决定用户的咨询由哪个客服来处理就是消息分流(通常消息分流会根据一系列规则来确定消息会分流给哪个客服,例如客服是否在线(客服不在线的话需要重新分流给另一个客服)、该消息是售前咨询还是售后咨询、当前客服的繁忙程度等等)。
12)信箱:本文的信箱我们指一个Timeline、一个收发消息的队列。
读扩散 vs 写扩散
IM系统里经常会涉及到读扩散和写扩散这两个技术概念,我们来看看。
读扩散
读扩散也称为“拉模式”,这应该是最符合我们认知直觉的一种技术实现方式。
原理如下图:
如上图所示:每一个内容发布者都有一个自己的发件箱(“我发布的内容”),每当我们发出一个新帖子,都存入自己的发件箱中。当我们的粉丝来阅读时,系统首先需要拿到粉丝关注的所有人,然后遍历所有发布者的发件箱,取出他们所发布的帖子,然后依据发布时间排序,展示给阅读者。
这种设计:阅读者读一次消息流,后台会扩散为N次读操作(N等于关注的人数)以及一次聚合操作,因此称为读扩散。每次读消息流相当于去关注者的收件箱主动拉取帖子,因此也得名——拉模式。
这种模式:
1)好处是:底层存储简单,没有空间浪费。
2)坏处是:每次读操作会非常重,操作非常多。
设想一下:如果我关注的人数非常多,遍历一遍我所关注的所有人,并且再聚合一下,这个系统开销会非常大,时延上可能达到无法忍受的地步。
因此:读扩散主要适用系统中阅读者关注的人没那么多,并且刷消息流并不频繁的场景。
拉模式还有一个比较大的缺点:就是分页不方便,我们刷微博或朋友圈,肯定是随着大拇指在屏幕不断划动,内容一页一页的从后台拉取。如果不做其他优化,只采用实时聚合的方式,下滑到比较靠后的页码时会非常麻烦。
写扩散
据统计:大多数消息流产品的读写比大概在100:1,也就是说大部分情况都是刷消息流看别人发的朋友圈和微博,只有很少情况是自己亲自发一条朋友圈或微博给别人看。
因此:读扩散那种很重的读逻辑并不适合大多数场景。
我们宁愿让发帖的过程复杂一些,也不愿影响用户读消息流的体验,因此稍微改造一下前面方案就有了写扩散。写扩散也称为“推模式”,这种模式会对拉模式的一些缺点做改进。
原理如下图:
如上图所示:系统中每个用户除了有发件箱,也会有自己的收件箱。当发布者发表一篇帖子的时候,除了往自己发件箱记录一下之外,还会遍历发布者的所有粉丝,往这些粉丝的收件箱也投放一份相同内容。这样阅读者来读消息流时,直接从自己的收件箱读取即可。
这种设计:每次发表帖子,都会扩散为M次写操作(M等于自己的粉丝数),因此成为写扩散。每篇帖子都会主动推送到所有粉丝的收件箱,因此也得名推模式。
这种模式可想而知:发一篇帖子,背后会涉及到很多次的写操作。通常为了发帖人的用户体验,当发布的帖子写到自己发件箱时,就可以返回发布成功。后台另外起一个异步任务,不慌不忙地往粉丝收件箱投递帖子即可。
写扩散的好处在于通过数据冗余(一篇帖子会被存储M份副本),提升了阅读者的用户体验。通常适当的数据冗余不是什么问题,但是到了微博明星这里,完全行不通。比如目前微博粉丝量Top2的谢娜与何炅,两个人微博粉丝过亿。
设想一下:如果单纯采用推模式,那每次谢娜何炅发一条微博,微博后台都要地震一次。一篇微博导致后台上亿次写操作,这显然是不可行的。
另外:由于写扩散是异步操作,写的太慢会导致帖子发出去半天,有些粉丝依然没能看见,这种体验也不太好。
通常写扩散适用于好友量不大的情况,比如微信朋友圈正是写扩散模式。每一名微信用户的好友上限为5000人,也就是说你发一条朋友圈最多也就扩散到5000次写操作,如果异步任务性能好一些,完全没有问题。
那对于上面说的超级大V到底是采用读扩散还是写扩散了,其实都不是,在业界还有另一种读写混合模式。
亿级架构核心点
由于概念比较多,一篇文章是不可能全部描述清楚的,还有像钉钉、微信与微博这种亿级海量用户的系统架构实现其实有很多难点,随便给你说几个,看下你自己是否知道!
1、亿级用户同时在线聊天如何保证高并发聊天消息正常推送
2、公众号千万级粉丝大V发文章如何让粉丝高效收取
3、高并发聊天系统如何保证发送的消息不乱序
4、微信钉钉后端海量离线消息如何高效存储与获取
5、高并发聊天系统如何保证发送的消息不丢失
6、单聊与群聊数据收发机制用读扩散还是写扩散
7、如何设计微博上亿粉丝大V消息收发架构
8、微信后端PB级海量历史聊天消息数据如何存储
9、应该如何架构微信春晚抢红包高并发系统
10、微信钉钉后端如何保证消息收发核心链路高可用
11、微信钉钉的群聊为什么要设置人数上限
12、如何架构微信后端百万在线直播互动系统
13、如何设计微信钉钉后端系统的缓存架构抗高并发
14、微信朋友圈日均千亿访问量背后会有哪些技术挑战
看完懵了么?再继续看下图,给大家写了一套亿级钉钉微信后端IM架构核心(1.0)的图,感觉怎么样?👇
如果你想了解这些架构技术,推荐你看下我朋友诸葛老师最近要做的一个技术分享《从NIO与Netty入门到微信钉钉后端IM架构实战》
9月15日晚上20:00开始直播,全程高能
限时优惠前150个名额
扫码抢占名额,免费领资料
👇👇👇
我为大家特别争取到金九银十面试涨薪课福利——前150名限时优惠0.02元,附赠一份2021最新版大厂面试真题集。
01
02
03
04
1、深入到源码级别,带你彻底理解Netty高并发高性能的架构设计思想
2、通过企业级实战IM项目,帮你掌握类似钉钉微信这种亿级用户架构项目的核心设计
3、 在简历上增加精通NIO模型与高性能框架Netty的底层原理与项目实战一项
4、在金九银十的面试中,能够很好的应对关于NIO与Netty的面试问题
2021最新版大厂面试真题集👇
9月15日晚上20:00开始直播,全程高能
限时优惠前150个名额
扫码抢占名额,免费领资料
👇👇👇
一起来搞定NIO模型与Netty架构
用实战IM项目为自己加分
👇戳阅读原文,可以直接进入福利课程