我们如何通过 RabbitMQ 分配工作,以便工作池可以根据彼此不同(但经常重叠)的标准订阅工作消息,但是当一条消息被路由到多个工作池时,只有一个工作人员会拿起工作?
简化示例:
- 我们有主机 1 和主机 2。
- Host1 处理classA 和classB 的工作;host2 处理 classB 和 classC 的作业。
- 如果我们路由一个 classA 的作业,只有 host1 会接它;如果我们路由 B 类的作业,host1 或 host2 会选择它(基于它们当前的负载/第一次可用),但绝不会两者兼而有之。
看起来我们需要使用主题交换,因为我们的路由标准很复杂,并且使用通配符为我们提供了我们想要的灵活匹配类型。
然而:
- 如果我们为工作池队列使用相同的名称(例如“worker-jobs”),我们会将所需的工作拆分给任意匹配的工作人员,但每个订阅命名队列的工作人员似乎都会用彼此的路由标准感染其他工作人员因为他们绑定它。即,路由键的绑定似乎在中央队列名称级别,而不是在连接到队列的基础上。
- 如果我们为每个工作池连接(比如“poolA-jobs”和“poolB-jobs”)使用不同的队列名称到同一个交换,那么我们可以获得所需的行为,在池之间维护不同的路由标准,但是进来的作业可以匹配 poolA 和 poolB 被路由到他们两个(尽管每个只有一个工人)。
笔记:
- 我没有详细说明原因,但我只想说我们有一个现有的多 PB 分布式搜索应用程序,它需要响应时间 < 50 毫秒。我们已经通过我们自己的自定义路由集线器实现了这一点,但如果我们能够获得所需的复杂路由,我们希望将其替换为 RabbitMQ,因为它的性能很有吸引力(就像退休的与通用社区项目重叠的自制代码一样)。
- 我们使用 Python
- 迪斯科不可行的原因有很多,太多了,无法进入。
- 它不一定是 RabbitMQ,但性能需要一样好。ØMQ 看起来非常有趣,并且可能同时提供灵活性和性能,但我们已经在使用 RabbitMQ,并且在阅读了色彩缤纷的 ØMQ 指南的前半部分之后,我仍然不确定它是否会支持我们需要的路由但是看起来我们几乎必须写一个经纪人来做这件事。
- 实际上,我们有幸知道哪些主机能够为哪些作业提供服务,所以我们可以做一些事情,比如让 host1 订阅 #.host1.#,让 host2 订阅 #.host2.#。然后当我们路由一个 classB 消息时,我们可以给它一个 host1.host2 的键来指示哪些后端可以接受服务。这简化了路由规则,但仍然没有解决所描述的问题。