【问题标题】:RabbitMQ plugin to remove duplicate messages用于删除重复消息的 RabbitMQ 插件
【发布时间】:2018-01-14 07:11:50
【问题描述】:

我有一个用于文档生成的 RabbitMQ 队列。基本上,每个文档都有typestate(新的、处理的、准备好的),所以我使用带有type.state 之类的路由键的主题交换。每次文档更改时,我都会将带有最后文档描述的消息发送到交易所,并且效果很好。

但有时文档可以被处理两次:

  1. 用户发送新文档。所以新消息report.new 被发送到交换。
  2. 当工作人员尚未开始文档处理(队列尚未到达)时,用户更新了文档。发送同一文档的新消息report.new
  3. 所以现在工人收到第一条消息并开始工作,而文档已更改,因此这项工作完全没有意义。

现在我只是将小代码添加到工作人员中,将消息中的last_modified 文档键与数据库中的键进行比较,如果它们不同,则确认消息。但是我认为这不是最好的解决方案。

我的想法是将ID 添加到消息头中,并使用一些RabbitMQ 插件从队列中删除具有相同ID 的旧消息。

谢谢。

附:也许另一个 MQ 引擎在这里有用?例如。也许ActiveMQ有这样的功能?

【问题讨论】:

    标签: rabbitmq message-queue


    【解决方案1】:

    好的,我读过 RabbitMQ 内部架构,发现这是不可能的。所以寻找它的人的方式。

    1. 仅在邮件正文中发送文档ID
    2. 为工作人员创建一个键值对存储(我为此使用了 memcached)。键是ID 值是最后一个工作人员为此ID 运行的时间戳。
    3. 当工作人员收到消息时,它会检查消息时间戳是否大于键值存储中的时间戳。如果是,则更新 store 中的时间戳并运行任务,否则跳过它。

    【讨论】:

    • Memcache 不是很好,因为它可能会在没有警告的情况下删除您的键/值。
    • 1) 键/值存储是否放置在您的交换/队列之前? 2) 如果我是从多个生产者那里写的并且不希望他们之间出现重复怎么办?
    • @eranotzap 没有得到您的第一个问题。关于第二个,没关系,因为去重是在接收阶段完成的。而且472084对他的评论完全正确,最好还是用Redis或者smth。
    • @Ximik 如果我想在发送端删除重复项怎么办。它是交易所原生支持的东西吗?这意味着我不想向客户发送重复的内容。我有一个恒定流和一个冗余流,我只想从其中一个发送。一个人可能会错过另一个人错过的事件,所以我不想填补空白
    • @eranotzap 我认为,这是不可能的。这些天来,卡夫卡提供了某种类似的功能(但仍然不完全是你想要实现的)。请参阅kafka.apache.org/documentation/#compaction 但是您仍然可以有重复项。而且它不是一个 MQ,而是更像一个流。
    【解决方案2】:

    您可以查看我写的这个plugin,它允许对代理中发布的消息进行重复数据删除。

    您可以根据需要在交换或队列中进行重复数据删除。您的发布者唯一需要做的就是将x-deduplicate-message 消息头设置为您的消息的ID

    【讨论】:

    • 如果我理解正确,它不会将重复的消息排入队列。我猜这个问题是关于将新消息排入队列并删除以前重复的消息。
    • 没错,在 RMQ 中删除旧消息是一个不小的问题,如果这是一个关键要求,我建议使用不同的排队系统。
    【解决方案3】:

    正如您所写,ActiveMQ has "duplicate message detection",但它的工作方式不同。它不会从队列中删除旧消息,但不会向队列中添加新消息。所以它的工作原理与plugin for RabbitMQ 相同。

    【讨论】:

      猜你喜欢
      • 2013-09-05
      • 1970-01-01
      • 2016-07-01
      • 2019-10-05
      • 2011-07-17
      • 2018-09-05
      • 1970-01-01
      • 1970-01-01
      • 2015-12-20
      相关资源
      最近更新 更多