You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Spring Boot+Websocket的指定Topic订阅者数量统计方案咨询

在线聊天室成员计数方案分析

针对你的需求,下面逐个分析你提到的方案,并给出适配场景的建议:

1. Singleton(单例内存存储)

  • 适用场景:仅单实例部署的小型应用
  • 优点:实现最简单,读写完全在内存,延迟极低,不需要额外依赖。
  • 缺点:
    • 集群部署时完全失效:每个实例维护独立的计数器,用户连接到不同节点会导致计数不一致。
    • 服务重启/崩溃后,计数器直接清零,无法恢复历史在线数据。
    • 无法自动处理用户异常断开(比如客户端直接关闭浏览器)的情况,除非手动在WebSocket断开事件里维护计数,但单例本身不提供持久化或分布式一致性保障。

2. MongoDB存储

  • 可行,但不是最优解
  • 优点:
    • 支持持久化,服务重启后可以恢复计数。
    • 集群部署时能保证数据一致性(MongoDB副本集/分片集群)。
    • 可以用原子操作$inc来保证计数的准确性,避免并发更新问题。
  • 缺点:
    • 高频读写场景下性能不如内存级存储:每次用户进出都要写磁盘(即使是MongoDB的内存映射引擎),延迟比Redis或内存单例高。
    • 如果需要实时显示在线人数,每次前端请求都查DB会增加不必要的开销,仍需结合缓存做优化。

3. 分布式缓存(比如Redis)

  • 推荐方案,尤其适合集群场景
  • 为什么适合:
    • Redis的INCR/DECR是原子操作,完美适配高频变更的计数器场景,单实例QPS轻松达到数万级,延迟极低。
    • 支持集群部署,天然解决多实例WebSocket节点的计数一致性问题。
    • 可选持久化(RDB/AOF),即使缓存重启,也能恢复大部分计数数据。
  • 实现要点:
    • 用户加入聊天室时,调用INCR chat:online:{channelId}。
    • 用户断开WebSocket时(通过HandlerInterceptor的afterCompletion方法),调用DECR chat:online:{channelId}。
    • 前端获取在线人数时,直接从Redis读取GET chat:online:{channelId},实时性拉满。

额外注意事项

  • 一定要处理用户异常断开的情况:WebSocket连接可能因为网络波动、客户端崩溃等原因异常关闭,你需要在SimpUserRegistry或者自定义拦截器里监听会话销毁事件,及时递减计数器,避免计数不准。
  • 如果你的应用目前是单实例,但未来有集群扩容计划,直接用Redis可以避免后续重构成本。

内容的提问来源于stack exchange,提问作者Allteran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 14:35:10