参考钉钉IM后端架构思路,本文聚焦IM网关后端三种主流架构模型,做对比分析,给出架构选型结论,同时完成单机房机器规模估算,最后对比Kafka与RocketMQ在IM场景下的优劣。
前言
IM网关的核心职责:维护海量客户端长连接(自研TCP、QUIC、WebSocket)、协议编解码、token鉴权、前置限流、报文校验;网关不适合承载过重业务逻辑 。网关向后端投递上行消息,一共有三种典型实现方案,不同方案在故障隔离、扩容成本、延迟、运维复杂度上差异巨大。钉钉这类亿级IM,核心思路就是长连接接入层与业务层、消息队列层做充分解耦,避免故障传导,支持接入层大规模独立扩容。

方案1:网关直接RPC调用Worker,Worker承担核心业务
链路:客户端 → IM网关 → Kitex RPC → Worker服务,Worker完成全部业务逻辑(消息校验、存储、会话、推送路由),同步返回应答给网关。
优点
-
链路简单,没有MQ引入,链路最短,没有消息队列带来的存储开销;
-
同步调用,发送结果可以实时返回客户端,消息发送成功失败即时反馈;
-
架构组件少,前期开发上手快。
缺点
-
网关与Worker强耦合,网关扩容会直接放大Worker的压力;如果部署100台网关,全部网关的上行流量全部打向Worker集群,Worker很容易被打满。
-
没有削峰能力,消息突增、群消息风暴会直接压垮Worker,进而造成网关大量RPC超时,大批量客户端发送消息报错。
-
Worker故障、慢逻辑、数据库抖动,直接传导到网关,引发大面积发送失败;长连接网关本身是高可用集群,后端业务抖动直接影响前端用户体验。
-
不方便做多消费组旁路处理,例如消息审计、统计、监控埋点,需要额外改造。
-
Worker既要执行业务逻辑,又要处理下行推送路由,职责耦合。
适用场景
小规模IM,消息QPS不高,没有大群消息风暴场景;不适合亿级大规模IM。
方案2:网关直接写Kafka,后端Worker消费Kafka承担任务
链路:客户端 → IM网关,网关内置Kafka生产者,直接将消息写入Kafka;Worker消费Kafka,执行业务逻辑。
优点
-
MQ天然削峰填谷,消息流量突增时Kafka缓冲,Worker可以按自身能力消费,隔离流量风暴;
-
网关与Worker完全解耦;支持多消费组,审计、统计可以独立消费topic,互不影响;
-
异步模型,Worker故障不会直接导致网关立刻报错。
缺点
-
网关集群全部持有Kafka生产者实例 。如果单机房部署100台网关,则同时存在100个Kafka生产者。生产者会维护元数据、连接、后台刷新任务;修改Kafka配置、生产者参数,需要全量发布全部100台网关,运维成本很高。
-
网关的核心压力是维持海量长连接,网关扩容时,Kafka生产者实例数量同步增加,会加重Kafka集群元数据压力。
-
网关职责变重:网关除长连接管理,还要维护Kafka客户端、处理生产者异常、重试逻辑;网关本应该只聚焦长连接,引入MQ客户端会增加网关故障风险。
-
消息发送变成异步,无法同步返回发送结果给客户端,客户端无法立刻知道消息是否发送成功,必须依靠回执机制确认。
适用场景
网关数量少的小规模集群;网关实例数少,运维压力可控。当网关达到几十上百台规模,该方案运维负担显著上升。
方案3:网关RPC调用接收服务,接收服务写Kafka,后端Worker消费处理
链路:客户端 → IM网关 → Kitex RPC调用接收服务 → 接收服务内部异步写入Kafka → Worker消费Kafka执行业务逻辑;Worker处理完成后,通过Kitex RPC回调网关完成下行消息推送。
核心设计:网关不直接操作Kafka;Kafka生产者全部收敛在少量接收服务实例;网关只负责长连接、协议解析、前置校验,通过内部RPC转发上行消息。
优点
-
网关集群与Kafka彻底解耦。网关可以大规模水平扩容,例如单机房100台网关用于承接海量长连接,网关扩容不会新增Kafka生产者实例,生产者集中在接收服务。修改Kafka生产者配置,仅需要发布接收服务,100台网关无需变更,运维成本低。
-
资源错配,资源利用率高:网关数量由在线长连接总数量决定 ;接收服务、Worker数量由消息QPS决定。在线连接很多,但消息QPS不高时,接收服务不需要和网关同步扩到100台,少量实例即可扛住写入压力,节约机器成本。
-
故障隔离:Kafka抖动、生产者重连异常,故障收敛在接收服务,不会影响全部网关集群;网关只感知Kitex RPC调用结果,具备熔断、超时、限流保护,保护长连接链路稳定。
-
接收服务统一完成消息标准化、partition key计算、生产者参数、埋点统计、异常监控,逻辑收敛,便于统一治理。
-
保留RPC调用的应答能力,网关可以拿到接收服务返回结果;RPC失败由上层IM协议
msg_id+客户端重传+送达回执做可靠性兜底。 -
Kafka之后支持多消费组,业务Worker、审计、统计服务独立消费,互不干扰。
缺点
-
相比方案1,多一跳Kitex RPC,内网环境增加1‑3ms P99延迟;小包IM场景可以接受。
-
新增接收服务这一个收敛节点,接收服务需要做好水平扩容,防止成为上行流量瓶颈。
-
RPC调用存在失败场景,不能依靠底层链路保证消息可靠,必须依靠IM上层业务msg_id幂等、客户端重传、送达回执机制兜底。
-
消息写入Kafka采用异步发送模式,接收服务返回成功不等于消息已经刷入磁盘,需要监控Kafka生产者回调异常指标,配置告警。
适用场景
大规模亿级IM,网关实例数量多,在线连接规模大,消息流量波动大,参考钉钉的分层接入思想,本方案作为最终选型。
架构选型结论
综合故障隔离、扩容能力、运维成本,最终选择方案3:网关RPC调用接收服务,接收服务写Kafka,后端Worker消费处理。
架构分层:
-
IM网关:负责长连接管理(自研TCP、QUIC、WebSocket)、协议解析、前置鉴权限流;网关通过Kitex调用接收服务;网关后期底层IO可基于netpoll做扩展,和Kitex技术栈统一。
-
接收服务:专门负责消息标准化、异步写入Kafka,收敛所有Kafka生产者逻辑。
-
Kafka:消息缓冲层。
-
Worker服务:消费Kafka,执行业务逻辑:消息存储、会话、权限、推送路由;Worker通过Kitex RPC回推消息到网关下发客户端。
单机房机器规模估算(前提:单机房100台IM网关)
说明:为工程经验估算,8核16G服务器,消息平均1KB,峰值QPS 15万消息/秒;实际生产需要根据压测结果调整,预留30%冗余。
-
IM网关:100台(给定条件) 职责:承接海量长连接,不执行业务,不操作Kafka。
-
接收服务(Kitex服务,专门写Kafka) 单实例稳定处理2‑3万QPS;峰值15万QPS,基础6台,加上30%冗余,部署8台接收服务。
接收服务数量由消息QPS决定,和网关100台数量无关,网关只做RPC调用。
-
Worker业务处理服务(消费Kafka执行业务逻辑) Worker要做消息解析、存储、数据库操作、会话逻辑;单实例处理8000‑12000 QPS;峰值15万QPS,基础13台,加冗余,部署18台Worker服务。
-
Kafka集群机器 IM场景,3副本;topic分区总数建议为Broker数量2‑3倍;峰值15万消息每秒。 部署6台Kafka Broker(3副本,2个broker一组副本) ,配套3台ZK;生产环境磁盘使用SSD,保障顺序写入性能。
备注:以上为业务消息链路机器,不包含Redis集群、数据库、监控、网关四层LB等基础设施机器。
Kafka与RocketMQ在IM场景优势对比
| 对比维度 | Kafka | RocketMQ |
|---|---|---|
| 设计定位 | 高吞吐流式日志系统,分区顺序写,零拷贝sendfile,追求极致吞吐 | 面向业务消息,内置重试、死信、事务消息、tag过滤,面向业务语义设计 |
| 吞吐量 | 更高,小消息下集群吞吐能力强,适合海量消息流转 | 吞吐略低于Kafka,但足以支撑亿级IM消息量 |
| 消费模型 | 以pull模式;没有内置重试、死信队列,业务侧自己实现 | push+pull双模式;原生内置重试队列、死信队列,对业务更友好 |
| 消息顺序 | 保证同一个partition内顺序 | 保证队列内顺序;支持严格顺序消息 |
| 事务消息 | 原生不支持事务消息,需要业务层封装 | 原生支持事务消息,适合和数据库原子落库场景 |
| 运维组件 | 无自带控制台,需要第三方工具;依赖Zookeeper(新版本可移除ZK) | 自带完善运维控制台,运维能力开箱即用 |
| 延迟消息 | 无原生支持,需要业务Redis轮询实现 | 原生支持延迟消息,IM离线通知、定时消息场景友好 |
| 堆积能力 | 极强,TB级消息堆积表现优秀 | 支持亿级消息堆积,同样可以支撑IM流量峰值 |
| 大厂实践 | 大量IM、流式场景使用 | 钉钉IM大规模生产落地,万亿级消息验证 |
IM场景选型总结
-
如果业务侧可以自行实现重试、死信逻辑,追求高吞吐、大消息堆积能力,选择Kafka;
-
如果业务希望MQ自带重试、死信、事务消息、延迟消息,减少业务开发工作量,选择RocketMQ;钉钉IM正是基于RocketMQ实现大规模企业IM消息流转。
-
本套架构选用Kafka,需要业务层自行处理消息重试、死信消息;接收服务做好消息幂等生产者配置。
结尾
网关后端架构的核心思想:网关只做长连接接入,把消息生产、业务处理向外剥离,做到接入层可以独立大规模扩容,故障不会相互传导。方案3通过独立接收服务收敛MQ生产者,在网关实例数量庞大的场景下,运维与稳定性收益最为突出。