rabbitmq - 队列公平性和消息服务器

标签 rabbitmq jms message-queue messaging

我正在寻找解决消息服务器和队列的 FIFO 性质的问题。在某些情况下,我想根据传递消息的顺序以外的标准将队列中的消息分发给消费者池。理想情况下,这将防止用户占用系统中的共享资源。以这个过于简化的场景为例:

  • 应用程序中有一项功能,用户可以通过该功能清空垃圾桶。
  • 此事件为垃圾桶中的每一项发送一条 DELETE 消息
  • 此队列的消费者调用具有限速 API 的 Web 服务。

鉴于每个用户的垃圾桶中都可能有大量消息,我们有什么选择可以允许并发处理每个垃圾桶而不考虑排队时间?在我看来,有一些明显的解决方案:

  • 为每个用户创建一个单独的队列和消费者池
  • 将消息从单个队列随机传递到单个消费者池

在我们的例子中,创建一个单独的队列并为每个用户管理消费者确实不切实际。可以做到,但我认为如果合理的话,我真的更喜欢第二种选择。我们正在使用 RabbitMQ,但如果有更适合此任务的技术,则不一定要依赖它。

我很喜欢使用 Rabbit 的消息优先级来帮助随机传递的想法。通过随机分配一条消息的优先级在 1 到 10 之间,这应该有助于分发消息。这种方法的问题在于,如果队列永远不会完全清空,则具有最低优先级的消息可能会永远卡在队列中。我以为我可以在消息上使用 TTL,然后使用升级的优先级重新排队消息,但我在 docs 中注意到了这一点:

Messages which should expire will still only expire from the head of the queue. This means that unlike with normal queues, even per-queue TTL can lead to expired lower-priority messages getting stuck behind non-expired higher priority ones. These messages will never be delivered, but they will appear in queue statistics.

我担心我可能会用这种方法进入兔子洞。我想知道其他人是如何解决这个问题的。我们将不胜感激任何有关创意路由、消息传递模式或任何替代解决方案的反馈。

最佳答案

所以我最终从网络路由器手册中取出了一页。这是路由器需要解决的问题,以允许公平的流量模式。 This video对问题和解决方案有很好的分解。

将问题翻译成我的领域:

Unfair Flows with a Single FIFO Queue

解决方案:

Fair Flows with Multiple FIFO Queues and a Load Balancer

负载均衡器是一个 channel 和已知数量队列的包装器,它使用加权算法在每个队列上接收的消息之间进行平衡。我们找到了一个 really interesting article/implementation到目前为止,这似乎运作良好。

使用此解决方案,我还可以在消息发布后确定工作区的优先级,以提高它们的吞吐量。这是一个非常好的功能。

摆在我面前的最大挑战是队列管理。将有太多的队列在很长一段时间内无法绑定(bind)到交易所。我正在开发一些工具来管理它们的生命周期。

关于rabbitmq - 队列公平性和消息服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37398634/

相关文章:

erlang - RabbitMQ (beam.smp) 和高 CPU/内存负载问题

java - JBoss EAP + WMQ 消息发送速度非常慢

java - 在Hornetq中配置发往 "Expired message address"的消息的过期时间

java - RabbitMQ 发送对象

RabbitMQ 启动时出错 - erlexec : HOME must be set

udp - 消息队列协议(protocol) : PGM vs UDP

python - celery 运行错误

go - 每个用户处理一条消息

node.js - 安排一个小时、一天、一周等时间的事件

Java EE 和应用程序服务器 - 我能做什么?