我是RabbitMQ的新手,我的任务是修复正在发生的负载平衡错误。
以下是设置: 我们使用RabbitMQ在RPC Api上运行Protobuf。
对api的请求将发布到Rabbit,然后由3个实例之一使用(API分布在3个应用程序实例中)。
每个实例都设置为使用10个线程来处理请求并返回响应。我们通过设置一个带有10个ConcurrentConsumers的SimpleMessageListener来实现这一点,这导致10个相应的线程处理每个消息。
这导致:
Instance 1: Consumers 1-10, Instance 2: Consumers 11-20, Instance 3: Consumers 21-30.
由于Rabbit使用循环方法在消费者之间分配负载(相对于应用程序实例分配负载)如果有5条消息通过,我们最终会看到这样的负载:
Instance 1: Threads 1-5 in use (6-10 idle), Instance 2: Idle, Instance 3: idle.
我想要发生的事情是: 5条消息:
Instance 1: Threads 1,2 in use, Instance 2: threads 1,2 in use Instance 3: Thread 1 in use.
换句话说,我想根据实例循环(例如实例1(消费者1),2(11),3(21),1(2),2(12))而不是消费者(例如,实例1,消费者1-5)。
使用Spring AMQP(1.2.1)和Spring Rabbit(1.2.1)库是否可以实现?我的第一个想法是将每个实例的并发使用者减少到1(因此兔子均匀地分配给应用程序的每个实例),然后使用执行程序为每个请求启动一个线程(每个实例最多10个线程)。
我还没有看到其他人遇到类似的问题,所以我希望有人可以给我一些指导!我主要试图看看我是否可以对我们当前的设置进行配置更改,或者我是否需要手动实现某些功能。
谢谢!
答案 0 :(得分:2)
如果您想循环到三台服务器,那么我认为您的想法(并发消费者= 1)是最佳选择。
您应该注意,它只是与应用程序连接以侦听消息的顺序一样公平,例如:
如果您的邮件中没有某种定位信息,那么您的最大努力将与您的流程连接以接收邮件一样有序。
但是,如果你的消费者数量为1并将消息传递给执行者并立即收听更多消息,我会打赌你会得到一个非常均匀的分发。
我还应该注意,您将在此设置中更难以使ACK / NACK变得更难。如果您正在使用Java 8,那么CompletableFuture
API可以很好地适用于从传递的线程中做一些直接的ACK / NACK
答案 1 :(得分:0)
您可以使用 consumer priorization 实现此行为。只需为每个实例的每个消费者提供 1-10 的优先级。由于文档,这应该平均分配工作负载。