简体   繁体   English

RabbitMQ 多线程多消费者负载均衡

[英]RabbitMQ Load Balancing Across Multiple Consumers with Multiple Threads

I'm fairly new to RabbitMQ and I've been tasked with fixing a load balancing bug that is occurring.我是 RabbitMQ 的新手,我的任务是修复正在发生的负载平衡错误。

Here is the setup: We operate a Protobuf over RPC Api utilizing RabbitMQ.这是设置:我们使用 RabbitMQ 在 RPC Api 上运行 Protobuf。

A request to the api will be published to rabbit which will be then be consumed by one of 3 instances (the API is distributed across 3 instances of the application).对 api 的请求将发布到 rabbit ,然后由 3 个实例之一使用(API 分布在应用程序的 3 个实例中)。

Each instance is set to utilize 10 threads to process the request and return a response.每个实例设置为使用 10 个线程来处理请求并返回响应。 We accomplish this by setting a up a SimpleMessageListener with 10 ConcurrentConsumers which results in 10 corresponding threads that handles each message.我们通过设置一个带有 10 个 ConcurrentConsumers 的 SimpleMessageListener 来实现这一点,这会产生 10 个相应的线程来处理每条消息。

This results in:这导致:

Instance 1: Consumers 1-10, Instance 2: Consumers 11-20, Instance 3: Consumers 21-30. 

Since Rabbit uses a round robin approach to distribute load across the consumers (vs distributing the load across the instances of the application) if 5 messages come through we end up seeing load like this:由于 Rabbit 使用循环方法在消费者之间分配负载(相对于在应用程序实例之间分配负载),如果通过 5 条消息,我们最终会看到这样的负载:

Instance 1: Threads 1-5 in use (6-10 idle), Instance 2: Idle, Instance 3: idle. 

What I want to have happen would be: 5 Messages:我想要发生的是: 5 条消息:

Instance 1: Threads 1,2 in use, Instance 2: threads 1,2 in use Instance 3: Thread 1 in use. 

In other words I would like to go round robin according to the instance (ex. Instance 1(consumer 1), 2(11), 3(21), 1(2), 2(12)) and not the consumer (ex. Instance 1, consumers 1-5).换句话说,我想根据实例(例如实例 1(消费者 1)、2(11)、3(21)、1(2)、2(12))而不是消费者(例如. 实例1,消费者1-5)。

Is this possible using Spring AMQP (1.2.1) and Spring Rabbit (1.2.1) libraries?这可以使用 Spring AMQP (1.2.1) 和 Spring Rabbit (1.2.1) 库吗? My first thought is to reduce the concurrent consumers per instance down to 1 (so rabbit distributes evenly to each instance of the application) and then use an executor to spin up a thread for each request (up to 10 threads total per instance).我的第一个想法是将每个实例的并发消费者减少到 1(因此 rabbit 平均分配给应用程序的每个实例),然后使用执行程序为每个请求启动一个线程(每个实例总共最多 10 个线程)。

I haven't seen anyone else facing a similar issue so I'm hoping someone can give me some guidance!我还没有看到其他人面临类似的问题,所以我希望有人能给我一些指导! I'm mainly trying to see if I can do config changes to our current set up or if I'll need to implement something manually.我主要是想看看我是否可以对我们当前的设置进行配置更改,或者我是否需要手动实现一些东西。

Thanks!谢谢!

If you want to round-robin to your three servers, then I think that your thought (concurrent consumers = 1) to be the best option.如果你想循环到你的三个服务器,那么我认为你的想法(并发消费者 = 1)是最好的选择。

You should note though, that it's only as fair as the order in which the applications connect to listen for messages, for example:但您应该注意,它仅与应用程序连接以侦听消息的顺序一样公平,例如:

  1. app1 listens app1 监听
  2. app2 listens app2 监听
  3. message dispatched to app1发送到 app1 的消息
  4. app1 listens app1 监听
  5. app3 listens app3 监听
  6. message dispatched to app2发送到 app2 的消息
  7. message dispatched to app1 *** this is not round-robin here消息发送到 app1 *** 这不是循环
  8. message dispatched to app3发送到 app3 的消息

Without having some kind of targeting information inside your messages, your best effort is going to be as orderly as your processes connect to receive messages.如果您的消息中没有某种目标信息,您的最大努力将与您的流程连接以接收消息一样有序。

But if you go down to a consumer count of 1 and hand off the message to an executor and immediately listen for more messages, I would wager you would get a pretty even distribution.但是,如果您将消费者数量降至 1,并将消息交给执行程序并立即侦听更多消息,我敢打赌您会得到相当均匀的分布。

I should also note, you're going to make ACK/NACK harder in this setup.我还应该注意,在此设置中,您将使 ACK/NACK 变得更难。 If you're using Java 8, the CompletableFuture API would fit nicely here to do some straightforward ACK/NACK from the handed off threads如果您使用的是 Java 8, CompletableFuture API 将非常适合从传递的线程中执行一些直接的 ACK/NACK

You can achive this behaviour with consumer priorization .您可以通过消费者优先级实现这种行为。 Just give every consumer on each instance a priorization from 1-10.只需为每个实例的每个消费者提供 1-10 的优先级。 Since documentation this should spread work load evenly.由于文档,这应该平均分配工作负载。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM