扩到两台机器后,A 机器上的用户发消息,B 机器上 400 个在线用户收不到,A 机器自己的 400 个正常,比例正好一半。日志里能对上时间点,这种反而好排。

房间成员表存在每个进程的内存里,广播循环只遍历本进程的连接集合,另一台机器根本不知道有这条消息。负载均衡按连接哈希,同一个人也不一定落在同一台。这一点先确认清楚,后面就不用反复试。

await pub.publish('room:1001', JSON.stringify(payload));
sub.on('message', (ch, msg) => localBroadcast(JSON.parse(msg)));

「多实例广播」改完先别急着全量,挑一台机器放半天,真有问题这段时间就能看出来。先做最小复现,能稳定跑出来的问题,排查成本会低一个数量级。

处理上按这个顺序:广播改走 Redis 发布订阅或消息队列 所有实例订阅同一频道;本机收到频道消息只推给本地连接 不要重复落库;房间成员改成集中存储 顺带解决跨机查询;两台机器各发一条测试消息 确认两边都收到。

结果对不对很好判断,两台实例各连一个客户端 任一边发消息 两边都在 200 毫秒内收到。

作者 9823189