为了账号安全,请及时绑定邮箱和手机立即绑定

如何仅使用消息 ID(在 Go 中)确认 Rabbitmq 消息?

如何仅使用消息 ID(在 Go 中)确认 Rabbitmq 消息?

Go
达令说 2021-11-08 15:45:30
我构建了一个小型服务器 (golang) 来从 RabbitMQ 获取消息并通过 Websocket 将它们传送到连接的浏览器。它工作得很好,但有一个警告:当通过 websocket 传递到浏览器时,消息会得到确认。对于大多数消息来说没问题,但有些消息可能非常重要。如果用户的浏览器收到了那些但用户没有看到消息,那么如果浏览器关闭或重新加载,它就会丢失。有没有办法稍后根据消息 ID(来自 Delivery 结构)确认消息?用例是当用户明确确认某些消息时会确认它们,然后将消息 ID 发送回工具以通过 RabbitMQ 进行确认。
查看完整描述

1 回答

?
跃然一笑

TA贡献1826条经验 获得超6个赞

即使你能做到这一点,这也是糟糕的设计。

如果用户没有看到消息会发生什么?您的网络服务器是否无限地挂在它上面?它是否将消息“nack”回队列?

这两种选择都不好。

坚持每条消息,RabbitMQ 将开始遇到来自大量用户的数千条未确认消息的问题。将消息返回到队列中,您将循环处理消息,增加 Web 服务器和 RMQ 服务器上的 CPU 资源,以及两者之间的网络流量。

这个问题更好的解决方案是将消息从RabbitMQ中拉出后存储在数据库中。当它被发送到浏览器/被浏览器查看时,更新数据库以反映这一点。

从我写的尚未发表的文章中:

将消息存储在数据库中。

向数据库记录添加一个字段,说明此消息属于谁。当用户稍后重新连接时,查询数据库以获取该用户当时需要查看和发送的任何消息。

上面开始的完整过程,然后变成了这样:

  • 用户的浏览器连接到 Web 服务器上的 SignalR/Socket.io/Pusher/websockets

  • Web 服务器检查队列中是否有在长时间运行的过程中发生的更新

  • 当登录用户的消息进来时

    • 如果用户已登录,则通过websocket向用户广播消息

    • 如果用户未登录,则将消息存储在数据库中

  • 当用户再次登录时,查询数据库并发送所有等待消息

这是在消息队列的想法出现之前你会做的事情,对吧?现在您也有一个消息队列,这应该是您要做的。


查看完整回答
反对 回复 2021-11-08
  • 1 回答
  • 0 关注
  • 267 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信