RabbitMQ和WebSocket

  消息路由规则(在消息处理服务中)

    • 逻辑:
      1. 用户 A 发送消息到 WebSocket 网关;
      2. 网关将消息存入 RabbitMQ 的公共队列(如chat_messages);
      3. 消息处理服务从队列消费消息,根据接收方 ID(如userB)查询会话管理服务,确定用户 B 的连接位置;
      4. 将消息转发到用户 B 所在的 WebSocket 网关对应的 RabbitMQ 队列(如gateway_2_messages);
      5. 用户 B 的 WebSocket 网关从队列消费消息,推送给用户。

  离线消息处理

  •   若用户 B 离线(会话管理服务查不到连接):
    1. 消息处理服务将消息标记为 “未读” 存入数据库;
    2. 用户 B 上线时,主动拉取离线消息;
    3. 通过 RabbitMQ 的死信队列(DLQ)处理多次推送失败的消息。

  架构优势

  1. 解耦网关与业务逻辑:WebSocket 网关只需收发消息,无需关心路由和存储。
  2. 水平扩展:
    • 增加 WebSocket 网关实例应对并发连接;
    • 增加消息处理服务实例提升消息吞吐量。
  3. 可靠性:RabbitMQ 确保消息至少被处理一次,数据库持久化保证消息不丢失。

  总结

  原架构图确实是 “客户端→数据库” 的简化版,但通过补充会话管理和消息路由逻辑,能完整实现 “用户 A→用户 B” 的消息流转。
  RabbitMQ 在其中的核心作用是:
      1.   异步解耦,提升响应速度;
      2.   可靠传输,确保消息不丢失;
      3.   负载均衡,支持水平扩展。 

 

具体分工:

  1. 消息队列的作用:路由到目标网关的队列
    当消息处理服务处理完消息后,会根据用户 B 当前连接的 “网关标识”(比如网关的 ID)生成一个路由键(例如 gateway_8_messages),然后将消息发送到 RabbitMQ 中与该路由键绑定的队列(每个网关会监听一个专属队列,比如网关 8 监听 gateway_8_messages 队列)。
    • 这里的 “路由” 是消息队列的核心能力:通过路由键匹配队列,确保消息能准确到达用户 B 所在的网关对应的队列中。
  2. WebSocket 网关的作用:从队列取消息并推送给用户 B
    每个 WebSocket 网关会持续监听自己专属的队列(比如网关 8 监听 gateway_8_messages)。当消息队列将用户 B 的消息路由到这个队列后,网关会从队列中取出消息,再通过自己与用户 B 已建立的 WebSocket 长连接,将消息推送给用户 B。

举个例子(用户 B 连接在网关 8):

  • 消息处理服务确定用户 B 在网关 8,于是用路由键 gateway_8 向 RabbitMQ 发送消息。
  • RabbitMQ 根据路由键,将消息存入网关 8 专属的队列 gateway_8_messages
  • 网关 8 监听这个队列,发现有新消息后,从队列中取出消息,通过自己与用户 B 的 WebSocket 连接,最终推送给用户 B。

关键区别:

  • 消息队列:负责 “把消息送对地方”(即目标网关的队列),靠路由键实现精准路由。
  • WebSocket 网关:负责 “把消息送出去”(即通过长连接推给用户 B),因为它持有与用户 B 的实时连接。

 

简单说:消息队列是 “快递分拣中心”(按地址分拨包裹到对应网点),WebSocket 网关是 “快递员”(从网点取包裹,送到收件人家中)。

 

 

核心逻辑再梳理:

  1. 长连接的角色:
    用户 A 和用户 B 的 WebSocket 长连接,只负责 “实时收发消息”(比如用户 A 发消息给网关,网关推消息给用户 B),但不处理复杂业务(如消息存库、判断用户 B 在哪台网关、过滤敏感词等)。这就像快递员只负责 “上门取件 / 派件”,但不负责 “分拣、打包、记录物流”。
  2. 消息队列的核心作用:
    它不仅是 “防击穿” 和 “持久化”,更重要的是 **“解耦” 和 “精准路由”**:
    • 解耦:WebSocket 网关只需要 “收消息→扔给队列” 和 “从队列取消息→推给用户”,不用关心 “消息该存到哪、该发给哪个用户、用户 B 在哪”,这些交给专门的 “消息处理服务” 去做。
    • 精准路由:消息处理服务确定用户 B 在 “网关 3” 后,会通过队列的路由键(如gateway_3)把消息扔进 “网关 3 专属队列”,确保只有网关 3 能拿到这条消息(避免其他网关乱推)。
  3. 完整链条的分工:
    • 用户 A → WebSocket 网关(收消息)→ 消息队列(暂存,转给处理服务)
    • 消息处理服务(从队列取消息→存数据库→查用户 B 在哪台网关→告诉队列 “这条消息该去网关 3 的队列”)
    • 消息队列(把消息路由到网关 3 的专属队列)
    • 网关 3(从自己的队列取消息→通过长连接推给用户 B)

举个生活类比:

  • 用户 A:发件人(写好快递)
  • WebSocket 网关:小区快递柜(收快递、通知收件人取件)
  • 消息队列:快递中转站(暂存快递,按收件人地址分到对应区域的快递柜)
  • 消息处理服务:快递分拣员(给快递贴地址标签、记录物流信息、决定该送哪个区域的快递柜)
  • 用户 B:收件人(从自己小区的快递柜取件)

 

简单说:WebSocket 网关是 “连接的维护者”,消息队列是 “消息的中转站”,消息处理服务是 “业务的决策者”。三者分工明确,才能支撑高并发、高可靠的即时通讯场景(比如几十万用户同时发消息)。
posted @ 2025-07-09 10:59  C豪  阅读(44)  评论(0)    收藏  举报