在发布消息之前选择消费者rabbitmq

时间:2016-07-20 21:02:49

标签: rabbitmq messaging soa nosql

我正在尝试构建一个系统,我需要选择下一个可用且合适的消费者从队列发送消息(或者可能是不使用队列的任何其他解决方案)

要求 我们有多个发布者/客户,他们会将对象(图像)发送到一方进行处理,多个分析师会处理它们,一旦处理完,发布者就会得到相应的响应。

发布商不关心哪位分析师会处理数据。

用户拥有一个Web应用程序,他们可以将每个客户端/发布者映射到一个或多个或所有代理,例如,如果Publisher P1映射到代理A& B,来自P1的所有对象都可以由代理A或代理B处理。注意:对象只能由一个代理处理。

根据映射,我应该有一个中间件,它使用来自所有发布者的消息并分发给代理

解决方案1 ​​ 我最初的想法是让所有发布者都发布他们的消息。代理发布消息的另一个队列,表示他们正在等待处理对象。

中间件选择消息,获取可以将消息发送到(从缓存数据库)的代理的可能列表,并通过代理队列查找下一个合适且可用的代理并将消息发布到该代理。

这个解决方案的问题是,如果我有代理队列像a,b,c,d那样,我收到的消息只能由代理处理b我会拒绝代理d& c并且它们最终会排在队列的尾部,我有大约180个代理,因此它们可能永远不会被选中,或者下一条消息只能由代理d处理(例如)我们必须拒绝所有代理才能到达那里

解决方案2 从发布者到中间件的第一位仍然是相同的

有一个扩展的快速nosql数据库,其中代理添加记录以通知可用性。基本上是一个关键值对

中间件从缓存中获取配置并从nosql数据库获取下一个可用+合适的代理将消息发送到代理的队列(通过直接交换)并更新nosql以设置isavailable false ad获取下一条消息。

此解决方案的问题是数据库和中间件可能成为瓶颈,如果我扩展中间件,我将最终遇到数据库并发问题,例如f我有两个中间件运行副本,每个都收到一条可以进行处理的消息由代理商A& B和两种代理都可用。 这两个中间件副本将查询数据库,并可能获得A作为可用,并最终将两个消息告诉A,而B仍在等待消息处理。

我将有大约100个出版商和180个代理商。

如何改进这些解决方案或任何其他可行解决方案的任何想法都将受到高度赞赏?

根据这一点,我还需要弄清楚代理如何将响应发送回发布者。

谢谢

3 个答案:

答案 0 :(得分:0)

我将从我的开源服务总线的角度来回答这个问题:Shuttle.Esb

通常,人们会忽略任何基于内容的路由并且只是拥有分发者模式。所有消息都将转到主端点,并将分发消息。但是,如果您决定坚持使用这些逻辑分组,则可以为每个逻辑分组(每个代理组)设置主端点。您仍然拥有主要端点,但不是将工作端点映射到代理,而是将代理分组映射到逻辑主端点,并且工作人员支持

然后,在主端点中,您将根据您的内容(作为代理标识符)将消息转发到相关的逻辑主端点。一直跟踪原始发件人。然后在工作人员中,您将邮件发送回原始发件人的队列。

我确信你可以使用任何服务总线做同样的事情。

答案 1 :(得分:0)

我在这里看到了几个要求,我认为可以归结为一些事情:

  • 发布商不关心哪个代理处理图片
  • 发布商需要知道图像处理何时完成
  • 代理商一次只能处理1张图片
  • 代理只能处理某些图像

这些假设是否正确?我错过了什么重要的事情吗?

如果没有,那么你的解决方案几乎内置于带有路由和队列的RabbitMQ中。不需要构建自定义中间层服务来管理它。

使用RabbitMQ,您可以将消费者设置为一次只处理1条消息。消费者设定了它的预取"限制为1,并使用" no ack"从队列中检索消息。设置为false - 意思是,它必须在处理完消息时确认消息。

要仅使用特定代理可以处理的消息,请使用RabbitMQ的多个队列路由功能。队列将根据图像类型或消费者可以选择图像的其他标准创建。

例如,如果有两种类型的图像:TypeA和TypeB,您将有2个队列 - 一个用于TypeA,一个用于TypeB。

然后,如果Agent1只能处理TypeA图像,那么它只会从TypeA队列中消耗。如果Agent2可以处理这两种类型的图像,它将从两个队列中消耗。

要将正确的图像放在正确的队列中,发布者需要使用正确的路由密钥。如果您知道图像类型(或任何选择条件),您将更改发布方的路由键以匹配该选择条件。 RabbitMQ中的路由将被设置为将TypeA的消息移动到TypeA队列等

最后一部分是对图像处理完成时的响应。这可以通过RabbitMQ"回复"来实现。字段和相关代码。它的要点是出版商拥有自己的专属队列。当它发布消息时,它在"回复"中包含它的专用队列的名称。消息的标题。当代理完成图像处理后,它会通过"回复"中找到的队列发回状态更新消息。头。该状态更新消息告诉生产者请求的状态。

从RabbitMQ的角度来看,可以使用此处的示例和文档将这些部分组合在一起:

http://www.rabbitmq.com/getstarted.html

具体看看这些:

您可以在这些文档中找到多种语言的示例。

我还在my RabbitMQ Patterns eBook

中涵盖了大多数这些场景(和其他场景)

答案 2 :(得分:-1)

由于发件人和收件人的总数只有几百个,如何为每个发件人创建一个队列。根据您的发送方接收方映射,接收方订阅发送方队列(更新映射更改的订阅)。您可以将接收器配置为仅在完成处理一条消息时从其订阅的所有队列(以随机方式)接收下一条消息。

相关问题