我构建了一个小型服务器(golang)来从RabbitMQ获取消息,并通过Websocket将它们传送到连接的浏览器。
它运作良好,但有一点需要注意:消息在通过websocket传递给浏览器时得到确认。对于大多数消息来说还可以,但有些消息可能非常重要。如果用户的浏览器收到了这些,但用户没有看到该消息,则在浏览器关闭或重新加载时它将丢失。
有没有办法根据消息ID(来自Delivery结构)稍后确认消息?
用例是当用户明确地确认消息时,某些消息被激活,此时消息ID被发送回工具以便用RabbitMQ确认。
答案 0 :(得分:2)
即使你能做到这一点,也是糟糕的设计。
如果用户没有看到该消息,该消息会怎样?您的Web服务器是否无限期地依赖它?是吗" nack"消息回队列?
这些选项都不好。
继续浏览每条消息,RabbitMQ将开始遇到来自许多用户的数千条未确认消息的问题。将消息重新发送回队列,然后您将消息圈成圆圈,在Web服务器和RMQ服务器上占用CPU资源,以及两者之间的网络流量。
此问题的更好解决方案是将消息从RabbitMQ中拉出后将消息存储在数据库中。当它被浏览器发送/查看时,更新数据库以反映它。
从一篇尚未发表的文章我写过:
将消息存储在数据库中。
在数据库记录中添加一个字段,说明此消息属于谁 至。当用户稍后重新连接时,查询数据库以查找任何内容 此用户此时需要查看和发送的消息。
完整的过程从上面开始,然后变为:
- 用户的浏览器连接到网络上的SignalR / Socket.io / Pusher / websockets 服务器
- Web服务器检查队列中是否存在长时间内发生的更新 正在运行的流程
- 当有登录用户的消息进入时
- 如果 用户登录后,通过websocket将消息广播到 用户
- 如果用户未登录,请将消息存储在数据库中
- 当用户再次登录时,查询数据库并发送所有等待 消息
在消息构思之前你会做些什么 排队进来玩吧?它应该是你现在要做的 你也有一个消息队列。