Claude Code Agent 权限控制 Prompt Injection AI Safety RAG LLM MiroThinker 长时序推理 MCP 上下文管理 容错机制 System Prompt Skills TypeScript Runtime Subagent 沙箱 逆向工程 工程实践 OpenIM Go 后端 死锁 Socket K8s 一致性Hash

独立部署OpenIM遇到的坑(3)扩容出错

公司项目有im场景,我们自己在k8s中部署了3.5.1版本的openim,在开发和运维的过程中,我们遇到了一些问题,这里记录一下问题详情和解决的过程。 问题简述 简单来说,就是:用户明明在线,但收不到实时消息,只能收到推送通知,过一会儿消息才出现在聊天界面。 这个问题只在扩容后出现,单个节点时一切正常。问题的根源是OpenIM内部的负载均衡机制出现了不一致,导致消息被发送到了错误的服务节点。 触发场景 对 openim-msggateway 进行扩容(从1个节点扩容到多个节点) 遇到的问题 扩容后在线用户无法收到后端推送的websocket消息,只能收到离线的通知栏推送消息,过一段时间后,可以在客户端的聊天界面中看到推送的消息 问题原理(通俗版) 在深入代码之前,我们先用一个比喻来理解这个问题: 想象一个快递系统: 📱 客户端:收件人 📍 openim-msggateway-proxy:客户服务中心(通过导航系统B给客户发分配快递站点) 🏠 openim-msggateway:快递站点(有多个) 🚚 openim-push:快递员(有自己的导航系统A) 实际的流程是: 建立连接:收件人先到客户服务中心,客户服务中心通过导航系统B为收件人分配快递站点A 投递包裹:快递员使用自己的导航系统A,独立计算这个收件人应该在哪个快递站点 正常情况下: 客户服务中心的导航系统B:收件人 → 站点A 快递员的导航系统A:收件人 → 站点A 收件人在站点A顺利收到包裹 但现在的问题是: 客户服务中心的导航系统B:收件人 → 站点A 快递员的导航系统A:收件人 → 站点B 收件人在站点A等包裹,快递员却把包裹送到了站点B 两个独立的导航系统给出了不同的结果! 技术原因分析 OpenIM内部连接链路 从图中可以看到,问题涉及两个独立的路由过程: 消息发送路径:openim-push 直接通过一致性hash找到用户连接的 openim-msggateway 节点 客户端连接路径:客户端通过 openim-msggateway-proxy 建立与 openim-msggateway 的websocket连接 这两个路径都需要通过一致性hash算法选择同一个 openim-msggateway 节点,但它们使用了不同的节点地址格式! 关键代码差异 问题的核心在于两个地方构建服务节点地址的方式不一致: 第一处:openim-push 侧(发送消息时) 1 2 3 4 // open-im-server/pkg/common/discoveryregister/kubernetes/kubernetes.go // 构建的地址格式(注意末尾的:88端口号) host := fmt.Sprintf("%s-openim-msggateway-%d.%s-openim-msggateway-headless.%s.svc.cluster.local:88", instance, i, instance, ns, port) 第二处:openim-msggateway-proxy 侧(建立连接时) ...

2026年2月12日 · 1 分钟 · 150 字 · Simon Sun