群聊开发10问:高性能IM群聊功能开发到底该怎么玩?

2026-04-28 0 890

突然想写点什么。

刚刚完成加班,窗外呈现出一片漆黑,脑海之中充斥着今天白天所探讨的那个群聊推送风暴的问题,有人表示直接采用copy-on-write就行,有人则称不行,必须运用推拉结合之人,为此争论许久也没有得出结论。

其实吧,做群聊开发最怕的不是技术难,是你根本不知道坑在哪。

踩过的人都懂。

群聊怎么做到真正实时

真的确确实实,在半年多的之前,在某个时段以内那是我头一回瞅见产品所给出的群聊延迟指标,简直差那么一点儿就没把我给气晕过去乃至背过气去了。竟然是小于200ms?你难道是觉得服务器就好像是你家自己开办拥有的一样啊。

但后来发现不是做不到。

在接入层这个部分,从进行轮询转变到采用长连,真的是一条充满艰难困苦的道路。只要是做过的人就会明白,轮询那一套在规模较小的站点还勉强能够应付,然而一旦数量上升,服务器方面就会直接崩溃。建立长连虽然操作起来较为麻烦,但是却是值得的。

B站群的延迟,能够达成100ms,并没有什么神秘手段,只是采用了推送以及读扩散的思路。

读扩散这东西……等等,我后面详细说。

消息会不会丢失

你永远忘不了线上第一次丢消息的场景。

你被用户@了,用户说,你们聊天是不靠谱的呀,我之前发的消息为何就消失了呢。

当时,你心里想着,要钻到屏幕里面去,跟他讲,不是东西丢了,而是客户端在没有收到回执的情况下,就断掉了连接。

太迟了。

所以,回执队列是必须要有的,简单来讲,存在着这样的情况,那就是发送者有一个队列,服务端也有一个队列,一旦出现超时却没有得到确认的状况,便会进行重发,千万不要嫌啰嗦,这可是血的教训啊!

可是大群难道就能够全部都去做ACK吗?我奉劝不要这样去做。消息风暴扩散系数要不要了解一下,五百人的群里把一条消息发出去,所收到的回执直接就能够冲垮接入层。批处理,一定要进行批处理。

百万群组怎么优化

那篇关于 Chat百万级群组优化的是我翻过的,端到端能在200ms以内达成,日均消息量可达千亿级,核心在于在线走写扩散,以及离线走读加上通知拉取。

关键是,不能一刀切。

小群(<100人):写扩散,每个成员的收件箱里复制一份,读起来飞快。

超大群体(人数达万人以上):还有谁居然能去写用来扩散的内容?一条信息要复制一万份,那样做简直就是自我毁灭行为。

那时候去查看底层的数据库排序情况,每个成员各自去获取自身的inbox,如此这般简单又直接。对于大群呢?那就规规矩矩采用读扩散方式,共同使用一个群信箱,是谁读了谁便去拉取。

说个细节——离线场景如何处理。

之前踩过坑,离线用户一上线就拉历史消息,直接把DB干崩了。

是腾讯云的一种推荐方式,采用分级存储,是热数据的话就通过Redis缓存来处理,属于冷数据的则丢弃到NoSQL中。之后能读取扩散群,在登录的时候仅仅同步最新的100条,对于历史消息是按照需求来加载的。千万别真的一次性全部拉取了啊。

读写扩散到底怎么选

单独进行聊天这件事是比较简单的,来写一下扩散方面的内容。你发送给我的那些消息都储存至我的信箱当中了,我不管在什么时候去阅读都是可以的。

但群聊不行。

最初的时候,我曾有过糊涂的行为——将所有的群设定为一致用写成扩散的方式来处理,后来当用户数量有所上升之后,就连晚上睡觉做梦的时候,脑海里浮现的都是报错日志。

融云所采用的方式能够当作参考答案来参考:它具备三级消息队列机制,在人数处于百人以下的情况下会走快速通道(也就是进行写扩散直推,确保时间在50毫秒以内能够完成这样的操作),而当群内人数达到千人时队列走向批量聚合的模式,对于万人级别的群组则采用慢速队列加上拉取模式来进行消息处理。

这逻辑就对了。

对不同群组规格,用不同策略。

未读计数怎么搞

有人说,未读数不就count一下表里的未读标记吗?

天真。

群聊场景下,有些人读了有些人没读,单靠表字段根本没法做。

当前的主流方案是,采用Redis来存储命令,把“群ID-用户ID”用来作为Key,Value所存储的是已读的最大消息ID,一切小于等于这个的消息统统都算已读。

特省事,还不会写数据库读到崩溃。

还有一个坑:批量入群怎么搞?

已有一万条消息的群里,用户被拉了进去,要是把这一万个未读标记逐个都写上一遍,服务器立刻就会爆炸。

高性能IM群聊功能开发

新成员同步的最佳实践是,只拉取上面所说的最新100条,历史消息则按需进行懒加载,切勿傻乎乎地全部塞过去。

消息存储怎么设计

我敢说,踩得最深的坑就是数据库设计。

常有的IM选型情况是,用于存储业务数据,Redis被用作热更新缓存,并且还要加上Kafka来处理消息队列。这三个组件,每一个都不能缺少。

美团使用的是分库分表方式用来存储数据,这种方式是按照时间范围以及用户ID进行分片处理的,其目的在于将热点数据打散开来,以此避免出现单点压力过大的情况。

还有,私聊和群聊不能当成两个完全不同的物种来设计。

有人将群聊表单独抽离并且设计出另一套全然独立的表引擎,然而两个系统彼此之间的消息同步情况,同时还有搜索以及统计方面,通通都紊乱交错毫无秩序了,像这样的事情千万别再去做了。

消息有序怎么做

群聊有序性的难点是什么?

不是技术,是分布式环境下的时序。

于单聊而言,能够凭借发送方的clk进行递增操作,然而群聊存在N个发送方,时间全然无法对上。

要如何处理呢?在服务器端进行单点序列化操作,所有进入群组的消息都经由同一条管道,依照消息到达的先后顺序来分配具备全局自增特性的消息ID,也就是。

这又带出了一个疑问,那便是,的ID生成要怎样确保在全局范围内都是独一无二的呢?

目前而言,雪花算法是最为靠谱可靠可信赖难以比及可比肩的,其64位长度被划分成三块,分别是时间戳(占据高41位),还有机器ID(为10位的长度所占),以及序列号(被设定为12位的长度涵盖)。由其生成的ID具备全局唯一的特性,并且呈现出循着趋势自动递增的态势,这对于数据库索引而言是颇为有利有助有益处的。

然而,雪花所存在的最大缺陷是时钟回拨,解决的办法是在内存之中保存最近生成的ID,要是新的ID比对旧的ID小,那么就在旧的ID基础之上加1。

只是群聊存有特殊场景,实际上并不需要全局都保持唯一,仅仅只要做到群内消息ID能够单调递增便可以了。而这通过Redis的incr就能够达成,更为简便。

这时候你再回来看协议层的设计。

被许多人所推荐的是与MQTT的组合,其中用于构建接入层,以此保障双方之间的通信能顺利进行,而MQTT则作为消息总线,承担起推送调度以及持久化的相关职责。

为啥这样进行如此搭配呢,原生对Web予以支持,然而却欠缺主题管理以及离线消息存储方面的机制,MQTT刚好能够补上这一短板之处。

另外还有一点需要予以提醒的是,层与Node层相互分离,其中网关仅仅承担认证以及路由的相关职责,而业务节点则负责处理实际存在的逻辑交互行为。如此这般能够带来便利的扩容效果,网关层在进行水平扩展时具有不限量的特性。

突然想起来。还有个事儿。

ACK收太多怎么办

大群的消息风暴根本不只是存储端的压力。

服务端推送了就能确保客户端收到了吗?不能。

均需每个要作返回确认的终端,都要作记录,每个被记录的都是确认。倘若每条消息于单独情形下进行确认之处境表现,对于服务器所造就的其冲击呈现出趋向乘方增长态势的情况也是存在的。

批量ACK是唯一的解法。

或者是客户端在接收好多条消息之后开展合并同时有一个确认包发送回去,又或者是服务端进行批量地刷入ACK队列。两者均能够大幅减少IO的次数,成本起码降低90%。

开发中到底踩了哪些坑

说来可能你不信——最大的坑是自己埋的。

一大群,不要轻易去搞那种强一致性,最终一致性就已经足够了。千万别跟自己过不去,搞强一致性就是等于将整个系统的吞吐一股脑压在一个点上面呀。

微服化完成后,服务情形日益增多,消息于服务之间流转的链路极为漫长。B站所采取的解决办法乃是将IM拆解为五个微服务,分别是单聊、群聊、系统通知、互动通知以及消息设置,借由领域边界去分隔不同的业务场景。

如此这般去做所具备的好处究竟是哪里出现了问题呢,能够直接精准地定位到那一项服务,从而不至于在一个模块发生故障坏掉的情况下,整个系统都陷入不可使用的状态。

群组此物,实则与之房间角色有别,群组并无“某台专属服务器存储”这般旧式游戏问题。数据存于DB即可,无状态服务方为真正的最佳实践。群组成员列表缓存一份至Redis,所有网关节点均可访问,无需为群组专门划出一台机器。

多端同步也是很多人忽略的一块。

一个人,其手机、PC同时处于在线状态,他于手机上所读过的消息,在PC上理应自动消失红点,这种一致性,必须依靠在服务端维护统一的消费日志方可得以实现。

而并非是将同步逻辑书写于客户端之中,那样如此数量达到几万个的客户端逻辑是极难实现对齐的。

讲了这般许多,实际上进行高性能群聊并非那般神秘莫测。压根归结起来就是这么一句话:依循具体的业务场景挑选最为合适的技术组合,不存在万能的解决方案。

小群借助写扩散,去追求那种极致的体验,大群运用读扩散,来扛住流量的峰值,离线用户优先考虑轻量化的存储以及历史按需拉取,消息风暴从ACK批处理着手降低成本。

该考虑的因素都考虑了,剩下的就是代码层面的事情了。

时间不早了,这篇碎碎念先写到这吧。

关于群聊开发还有想问的吗?评论留下你的问题,我看到会回复。

申明:本文由第三方发布,内容仅代表作者观点,与本网站无关。对本文以及其中全部或者部分内容的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。本网发布或转载文章出于传递更多信息之目的,并不意味着赞同其观点或证实其描述,也不代表本网对其真实性负责。

七爪网 行业资讯 群聊开发10问:高性能IM群聊功能开发到底该怎么玩? https://www.7claw.com/2827720.html

七爪网源码交易平台

相关文章