1、立项背景和目标:在直播和社交场景中,IM是核心基础设施但第三方SDK费用高且不可控,自研Erlang方案门槛又太高。目标是基于Go构建一个轻量级高并发IM网关,单机承载10万级WebSocket长连接,支持单聊、群聊和离线消息,让中小团队无需依赖第三方即可搭建自有IM服务。
2、核心功能模块:(1)连接管理模块——基于gorilla/websocket实现读写分离的双goroutine模型,每个连接独立管理心跳、超时、缓冲区;(2)自研二进制协议——8字节定长头+变长payload,相比JSON压缩约70%传输量,支持13种操作码覆盖认证/消息/房间/同步等场景;(3)Hub消息分发中心——单goroutine事件循环管理连接注册/注销/消息路由,房间广播采用快照读写分离避免锁竞争;(4)离线消息队列——基于Redis Sorted Set按时间戳排序存储,上线后通过SyncReq拉取增量消息;(5)房间系统——支持动态加入/退出/广播,Presence通知实时感知成员变化。
3、业务流程:客户端通过HTTP获取JWT Token → 建立WebSocket连接 → 发送Auth包完成认证 → 单聊发Msg包(Hub查表转发或写离线队列)→ 群聊发JoinRoom+RoomMsg包(Hub广播给房间成员)→ 离线用户上线后发SyncReq拉取未读消息。
1、整体架构:采用单进程多goroutine模型,Gin负责HTTP控制面(Token签发、健康检查、房间管理),核心数据面全部走WebSocket+自研二进制协议。Hub作为中央消息总线,单goroutine处理Register/Unregister/Inbound三个channel,避免加锁。存储层用Redis做离线消息持久化和集群间Pub/Sub转发。部署用Docker Compose一键拉起Redis+网关服务。
2、我的负责模块和结果:(1)独立设计并实现了自研二进制协议,包含编解码器和5种Payload序列化方案,经压测验证比JSON方案降低约70%传输量;(2)实现Hub消息分发中心,单节点稳定承载10万并发WebSocket连接,消息吞吐量约85000 msg/s,P99延迟38ms;(3)实现离线消息队列,基于Redis ZSET保证消息按序存储,7天自动过期;(4)编写Node.js压测脚本,输出完整的并发/吞吐/延迟报告。
3、遇到的难点和解决方案:(1)10万连接内存占用过高——将每个连接的send channel从1024降到256,配合非阻塞发送+满则断连策略,内存从4.2GB降到2.1GB;(2)房间广播时遍历成员表导致锁持有时间长——改为先RLock快照成员列表再释放锁逐个发送,将广播耗时从120ms降到15ms;(3)断连检测不准——用atomic.Bool替代mutex+flag,避免Close()被重复调用导致channel panic。