有序队列的多线程消耗

时间:2015-06-22 15:07:47

标签: java multithreading rabbitmq amqp

我有来自第三方消息队列的对象增量流(即描述对其他对象的更改的JSON对象)。我需要将这些应用于数据库中的相应对象(将增量转换为状态)。三角洲本质上是有序的。

实际上,我打算将这些增量管道传输到我们自己的RabbitMQ集群中,然后一组Java服务器将它们拉出来然后将它们应用到数据库中(Java是数据库更新逻辑集中的地方)。 p>

增量的应用需要多线程,但我想确保始终按顺序应用给定对象的增量。为了真正保证这一点,只有一个线程可以处理给定对象的增量。

为此,当我将它们从第三方队列中读出并在将它们放入RabbitMQ之前,我想我可以通过相应对象的uuid将增量分成队列。基本上,每个delta都有一个object_uuid字段,我将这个uuid模数为50,然后使用结果作为路由键,这样我就可以在RabbitMQ中拥有50个有序增量队列。

此时,简单地说(heh)确保每个队列都有一个消费者(尽管每个消费者我仍然可以拥有多个队列)。我认为AMQP中队列声明的'exclusive'参数可能会给我所需的行为,而且它确实如此,但遗憾的是它带来了消费者断开连接时队列被删除的禁止性副作用(这是一个Java队伍)随每个版本上下的服务器 - 队列必须在发布之间保持不变。)

这不是一个不寻常的困境,但我没有看到任何非常适合这个问题的东西。在RabbitMQ或AMQP中是否没有我可以在这里使用的构造?有没有办法可以重新考虑这个避免问题的问题?或者我是否需要查看分布式锁定解决方案?

1 个答案:

答案 0 :(得分:0)

这是我从您的问题中理解的:您基本上拥有N个对象,每个对象都有M*个状态。您希望这些N个对象中的每一个都在不同的进程/线程上运行,但是对于属于M*的{​​{1}}状态(来自n)要按顺序应用。

您建议的解决方案对我来说很好。我要做的是:

对于每个对象,创建一个单独的队列(称为N),根据您的帖子,它基本上是对象的UUID。

然后你有一个服务器/分销商,有三个目的:

  1. 创建持久性队列N'
  2. 将一个代理池随机分配给此主题并与其进行通信
  3. 每隔一段时间听取这些代理人的心跳消息,以确保他们活着。如果他们不是,请随机选择另一个可用代理并将队列分配给他们。
  4. 要使此分发服务器也崩溃/重启安全,它可能应该在启动时检查现有队列并确保将它们分配给某个代理。如果没有,它应尽快分配。

    您的代理商自己负责:

    1. 聆听经销商的队列分配
    2. 处理分配队列中的项目(M'州)
    3. 向经销商发送心跳
    4. 确保每个代理人N'的工作在于经销商。它不应该是其他任何人的责任,你不能真正安全地将这项工作用于消息传递技术,或者至少我不知道任何可以处理这个问题的队列但是解决方案应该以某种方式帮助解决您的问题。

      可能出现的另一个问题是何时删除队列。您可以在代理商自己处理所有内容时执行此操作,但您需要确保他们只在与分销商的共享锁中执行此操作。你不想要的是删除你认为是空的但是分发者即将写入的队列。