Select消费者在rabbitmq发布消息之前
Select consumers before publishing a message rabbitmq
我正在尝试构建一个系统,我需要 select 下一个可用且合适的消费者从队列发送消息(或者可能是任何其他不使用队列的解决方案)
要求
我们有多个 publishers/clients 将对象(图像)发送到一侧进行处理,多个分析师将处理它们,一旦处理,发布者应该得到相应的响应。
发布者不关心哪个分析师将处理数据。
用户有一个 Web 应用程序,他们可以在其中将每个 client/publisher 映射到一个或多个或所有代理,例如,如果发布者 P1 映射到代理 A 和 B,则可以处理来自 P1 的所有对象由代理A或代理B处理。注意:一个对象只能由一个代理处理。
根据映射,我应该有一个中间件,它使用来自所有发布者的消息并分发给代理
解决方案 1
我最初的想法是有一个队列,所有发布者 post 他们的消息。代理发布消息说他们正在等待处理对象的另一个队列。
中间件挑选消息,获取它可以将消息发送到的可能代理列表(从缓存数据库)并通过代理队列找到下一个合适和可用的代理并将消息发布到该代理。
此解决方案的问题是,如果我有像 a、b、c、d 这样的代理队列,并且我收到的消息只能由代理 b 处理,我将拒绝代理 d 和 c,他们最终会在队列的尾部,我有大约 180 个代理,所以他们可能永远不会被选中,或者如果下一条消息只能由代理 d 处理(例如),我们必须拒绝所有代理到达那里
解决方案 2
从发布者到中间件的第一位仍然相同
有一个扩展的快速 nosql 数据库,代理在其中添加一条记录以通知那里的可用性。基本上是一个键值对
中间件从缓存获取配置并从 nosql 数据库获取下一个可用 + 合适的代理将消息发送到代理的队列(通过直接交换)并更新 nosql 以设置 isavailable false ad 获取下一个消息。
此解决方案的问题是数据库和中间件可能成为瓶颈,而且如果我扩展中间件,我最终会遇到数据库并发问题,例如 f 我有两个中间件副本 运行,每个副本都收到可以由代理 A 和 B 处理的消息,并且两个代理都可用。
两个中间件副本将查询数据库并可能获得可用的 A,并最终将两条消息发送给 A,而 B 仍在等待消息处理。
我将有大约 100 个发布商和 180 个代理商开始。
如果有任何改进这些解决方案或任何其他可行解决方案的想法,我们将不胜感激?
据此我还需要弄清楚代理如何将响应发送回发布者。
谢谢
我从我的开源服务总线的角度来回答这个问题:Shuttle.Esb
通常情况下,人们会忽略任何 基于内容的路由,而只使用分发器模式。所有消息都转到主要端点,它将分发消息。但是,如果您决定坚持使用这些逻辑分组,您可以为每个逻辑分组(每个代理组)设置主要端点。您仍将拥有主要端点,但不是将工作人员端点映射到代理,而是将代理分组映射到逻辑主要端点,工作人员支持 that.
然后在主要端点中,您将根据您的内容(作为代理标识符)将消息转发到相关的逻辑主要端点。在您跟踪原始发件人的同时。然后,在工作人员中,您会将消息发送回原始发件人的队列。
我相信您可以使用任何服务总线做几乎相同的事情。
由于发送者和接收者的总数只有数百个,如何为每个发送者创建一个队列。根据您的发送者接收者映射,接收者订阅发送者队列(更新订阅映射更改)。您可以将接收器配置为仅在处理完一条消息时从它订阅的所有队列(以随机方式)接收下一条消息。
我看到这里有几个要求,可以归结为几件事,我认为:
- 发布者不关心哪个代理处理图像
- 发布者需要知道图像处理何时完成
- 代理一次只能处理 1 张图像
- 代理只能处理某些图像
这些假设是否正确?我错过了什么重要的事情吗?
如果没有,那么您的解决方案几乎已内置到具有路由和 queues 的 RabbitMQ 中。应该不需要构建自定义 middle-tier 服务来管理它。
使用 RabbitMQ,您可以将消费者设置为一次仅处理 1 条消息。消费者将其 "prefetch" 限制设置为 1,并从 queue 检索一条消息,其中 "no ack" 设置为 false
- 意思是,它必须在完成处理后确认消息它。
要仅使用特定代理可以处理的消息,请将 RabbitMQ 的路由功能与多个 queue 一起使用。 queue 将根据图像类型或消费者可以 select 图像的其他一些标准创建。
例如,如果有两种类型的图像:TypeA 和 TypeB,您将有 2 个 queues - 一个用于 TypeA,一个用于 TypeB。
那么,如果 Agent1 只能处理 TypeA 图像,它只会从 TypeA 中消费 queue。如果 Agent2 可以处理这两种类型的图像,它将消耗两个 queues.
要将正确的图像放在正确的位置 queue,发布商需要使用正确的路由键。如果您知道图像类型(或 selection 标准是什么),您将更改发布者端的路由键以匹配该 selection 标准。 RabbitMQ 中的路由将设置为将 TypeA 的消息移动到 TypeA queue,等等
最后一部分是在图像处理完成时获得响应。这可以通过 RabbitMQ 的 "reply to" 字段和相关代码来完成。其要点是发布者拥有自己的独家 queue。当它发布消息时,它在消息的 "reply to" header 中包含它独有的 queue 的名称。当代理完成图像处理后,它会通过 "reply to" header 中的 queue 发回状态更新消息。该状态更新消息告诉生产者请求的状态。
从 RabbitMQ 的角度来看,可以使用此处的示例和文档将这些部分组合在一起:
http://www.rabbitmq.com/getstarted.html
具体看这些:
- 工作Queues:http://www.rabbitmq.com/tutorials/tutorial-two-python.html
- 主题:http://www.rabbitmq.com/tutorials/tutorial-five-python.html
- RPC(又名 Request/Response):http://www.rabbitmq.com/tutorials/tutorial-six-python.html
您会在这些文档中找到多种语言的示例。
中涵盖了大部分这些场景(和其他场景)
我正在尝试构建一个系统,我需要 select 下一个可用且合适的消费者从队列发送消息(或者可能是任何其他不使用队列的解决方案)
要求 我们有多个 publishers/clients 将对象(图像)发送到一侧进行处理,多个分析师将处理它们,一旦处理,发布者应该得到相应的响应。
发布者不关心哪个分析师将处理数据。
用户有一个 Web 应用程序,他们可以在其中将每个 client/publisher 映射到一个或多个或所有代理,例如,如果发布者 P1 映射到代理 A 和 B,则可以处理来自 P1 的所有对象由代理A或代理B处理。注意:一个对象只能由一个代理处理。
根据映射,我应该有一个中间件,它使用来自所有发布者的消息并分发给代理
解决方案 1 我最初的想法是有一个队列,所有发布者 post 他们的消息。代理发布消息说他们正在等待处理对象的另一个队列。
中间件挑选消息,获取它可以将消息发送到的可能代理列表(从缓存数据库)并通过代理队列找到下一个合适和可用的代理并将消息发布到该代理。
此解决方案的问题是,如果我有像 a、b、c、d 这样的代理队列,并且我收到的消息只能由代理 b 处理,我将拒绝代理 d 和 c,他们最终会在队列的尾部,我有大约 180 个代理,所以他们可能永远不会被选中,或者如果下一条消息只能由代理 d 处理(例如),我们必须拒绝所有代理到达那里
解决方案 2 从发布者到中间件的第一位仍然相同
有一个扩展的快速 nosql 数据库,代理在其中添加一条记录以通知那里的可用性。基本上是一个键值对
中间件从缓存获取配置并从 nosql 数据库获取下一个可用 + 合适的代理将消息发送到代理的队列(通过直接交换)并更新 nosql 以设置 isavailable false ad 获取下一个消息。
此解决方案的问题是数据库和中间件可能成为瓶颈,而且如果我扩展中间件,我最终会遇到数据库并发问题,例如 f 我有两个中间件副本 运行,每个副本都收到可以由代理 A 和 B 处理的消息,并且两个代理都可用。 两个中间件副本将查询数据库并可能获得可用的 A,并最终将两条消息发送给 A,而 B 仍在等待消息处理。
我将有大约 100 个发布商和 180 个代理商开始。
如果有任何改进这些解决方案或任何其他可行解决方案的想法,我们将不胜感激?
据此我还需要弄清楚代理如何将响应发送回发布者。
谢谢
我从我的开源服务总线的角度来回答这个问题:Shuttle.Esb
通常情况下,人们会忽略任何 基于内容的路由,而只使用分发器模式。所有消息都转到主要端点,它将分发消息。但是,如果您决定坚持使用这些逻辑分组,您可以为每个逻辑分组(每个代理组)设置主要端点。您仍将拥有主要端点,但不是将工作人员端点映射到代理,而是将代理分组映射到逻辑主要端点,工作人员支持 that.
然后在主要端点中,您将根据您的内容(作为代理标识符)将消息转发到相关的逻辑主要端点。在您跟踪原始发件人的同时。然后,在工作人员中,您会将消息发送回原始发件人的队列。
我相信您可以使用任何服务总线做几乎相同的事情。
由于发送者和接收者的总数只有数百个,如何为每个发送者创建一个队列。根据您的发送者接收者映射,接收者订阅发送者队列(更新订阅映射更改)。您可以将接收器配置为仅在处理完一条消息时从它订阅的所有队列(以随机方式)接收下一条消息。
我看到这里有几个要求,可以归结为几件事,我认为:
- 发布者不关心哪个代理处理图像
- 发布者需要知道图像处理何时完成
- 代理一次只能处理 1 张图像
- 代理只能处理某些图像
这些假设是否正确?我错过了什么重要的事情吗?
如果没有,那么您的解决方案几乎已内置到具有路由和 queues 的 RabbitMQ 中。应该不需要构建自定义 middle-tier 服务来管理它。
使用 RabbitMQ,您可以将消费者设置为一次仅处理 1 条消息。消费者将其 "prefetch" 限制设置为 1,并从 queue 检索一条消息,其中 "no ack" 设置为 false
- 意思是,它必须在完成处理后确认消息它。
要仅使用特定代理可以处理的消息,请将 RabbitMQ 的路由功能与多个 queue 一起使用。 queue 将根据图像类型或消费者可以 select 图像的其他一些标准创建。
例如,如果有两种类型的图像:TypeA 和 TypeB,您将有 2 个 queues - 一个用于 TypeA,一个用于 TypeB。
那么,如果 Agent1 只能处理 TypeA 图像,它只会从 TypeA 中消费 queue。如果 Agent2 可以处理这两种类型的图像,它将消耗两个 queues.
要将正确的图像放在正确的位置 queue,发布商需要使用正确的路由键。如果您知道图像类型(或 selection 标准是什么),您将更改发布者端的路由键以匹配该 selection 标准。 RabbitMQ 中的路由将设置为将 TypeA 的消息移动到 TypeA queue,等等
最后一部分是在图像处理完成时获得响应。这可以通过 RabbitMQ 的 "reply to" 字段和相关代码来完成。其要点是发布者拥有自己的独家 queue。当它发布消息时,它在消息的 "reply to" header 中包含它独有的 queue 的名称。当代理完成图像处理后,它会通过 "reply to" header 中的 queue 发回状态更新消息。该状态更新消息告诉生产者请求的状态。
从 RabbitMQ 的角度来看,可以使用此处的示例和文档将这些部分组合在一起:
http://www.rabbitmq.com/getstarted.html
具体看这些:
- 工作Queues:http://www.rabbitmq.com/tutorials/tutorial-two-python.html
- 主题:http://www.rabbitmq.com/tutorials/tutorial-five-python.html
- RPC(又名 Request/Response):http://www.rabbitmq.com/tutorials/tutorial-six-python.html
您会在这些文档中找到多种语言的示例。
中涵盖了大部分这些场景(和其他场景)