行业资讯

染信IM:一套Go+Flutter源码搞定四端即时通讯,聊聊我们踩过的坑和架构决策

高染网络·2026-06-12·104 阅读

摘要:染信IM是原创开发的全平台IM系统,基于Go、Flutter、MySQL和Redis,支持iOS、Android、Web和桌面。文章从实战角度分享架构难点:64分片锁降低锁竞争、多Worker处理WebSocket、Redis消息队列应对流量洪峰,以及音视频通话集成声网的经验。适合考虑私有化部署IM的团队参考。

一套代码四端跑通,真不只是口号

去年我们决定自研IM的时候,团队里争论过好几次:是用现成的框架还是从头撸?最后选了后者,因为要给客户提供能上架应用商店的私部署方案,必须保证每个端都原生体验。现在你看到的染信IM,iOS、Android、Web、桌面端,核心逻辑用Go写后端,Flutter做跨平台UI,MySQL存关系型数据,Redis扛缓存和队列。

最早版本我只做了单机单锁,上线一压就跪。后来重构了架构,才敢说能扛百万级。这篇文章不贴PPT,就聊聊实际开发里我们怎么解决并发、消息延迟、媒体加载这些真实问题。

64分片锁:为什么我不再怕百万并发

传统IM最头疼的是消息序号的互斥。早期我用一个全局互斥锁(mutex),100个并发写进来只能排队。压测到2000QPS时,延迟飙升到300ms。后来改成64分片锁——用FNV哈希把用户ID散列到64个锁里,锁竞争理论上降低64倍。实际测试里,不同分片的用户完全不会互相阻塞,同一分片内请求还是串行,但哈希均匀分布后,单锁的压力从100%降到约1.5%。

坑点:哈希碰撞导致热点用户集中在同一分片。我们后来加了二级分流:先按用户ID取模分片,如果发现该分片排队数超过阈值,就动态拆出新分片。这个优化让高峰期消息序号生成成功率从99.2%提升到99.97%。

多Worker + 缓冲通道:WebSocket连接的“呼吸阀”

WebSocket连接管理我踩过最大的坑:连接建立和消息推送争抢同一个goroutine池,导致新连接握手时,老用户的消息卡住。解决方法是用多个Worker池分工:8个注册Worker专门处理连接建立/断开,16个广播Worker并行推送消息。

还有一个关键设计:5万条消息的缓冲通道。当流量洪峰时,广播Worker来不及消费,消息会先进入通道,不会立即阻塞注册流程。曾经双11峰值时有瞬间10万条消息涌入,通道填满后触发了背压机制,客户端收到“服务器忙”重试指令,避免了雪崩。

实际效果:消息延迟从之前的平均200ms降到20ms以内(排除网络因素),而且连接成功率接近100%。

Redis消息队列:优先级、延时、死信,一个都不少

消息队列我们用了Redis List,但做了三层分级:优先级队列(系统通知、红包这类必须秒达)、延迟队列(定时消息,比如“记得下午开会”)、死信队列(失败超过3次的消息)。100个Worker并发消费,每次批量取100条,减少IO开销。

说个血泪教训:早期没做死信队列,一条图片消息因为媒体服务器超时重试了20次,把整个队列堵死。后来改成指数退避:第一次失败等10毫秒,第二次100毫秒,第三次1秒...同时直接丢进死信队列,人工介入排查。现在队列积压情况几乎为零。

音视频通话:集成声网的那些坑与优化

通话模块我们集成了声网Agora SDK。起初觉得很简单,不就是推流拉流嘛?实际联调时发现:安卓端和iOS端的音频编解码参数必须一致,否则会有回声。还有弱网下的策略:我们配合声网做了动态码率调整,网络差时自动降到240p+单声道,加上FEC前向纠错,通话接通率从82%涨到96%。

另外,为了匹配IM系统,通话邀请逻辑我们自己写:用户A发起呼叫后,服务端通过WebSocket推送给B的客户端,同时启动一个30秒超时计时器。如果B不在线,转接为离线通知。这个流程需要与声网的频道做状态同步,调试时发现过竞态条件(B先加入频道再收到呼叫),后来加了UUID去重才搞定。

媒体加载与内存优化:不能让用户看到“加载中”

很多IM系统图片加载慢,是因为直接请求原图。我们在Flutter层做了分层缓存:预览图(256x256)、缩略图(720p)、原图。服务器端用nginx的image_filter模块实时裁剪,CDN回源时只存一份原图。客户端预加载策略是:聊天列表可见区域外10张图片预拉取缩略图,用户滚到位置时直接显示,基本秒开。

内存优化方面,Flutter的ListView如果加载大量图文消息,很容易OOM。我们用了分页+复用,每页50条消息,超出范围的消息释放图片缓存。同时限制单条消息内图片数量不超过9张,防止用户一次性发太多。测试机(华为P30)上,连续滚动3000条消息无卡顿。

说在最后:为什么我们坚持原创并持续更新

染信IM的每一行代码都是我们团队自己写的,不是简单拼凑开源库。从架构设计到上架审核踩过的坑(比如苹果ATS要求、安卓前台权限申请),我们都固化成了文档和回调接口。目前这套源码售价35000元,买断后永久享受更新,包括新功能(比如正在做的小程序版)和bug修复。如果你正在做类似于知识付费、在线教育或企业内部通讯的产品,不妨看看我们的演示站,能实际体验再决定。