6

There are multiple articles suggesting that load-balancer should be used in front of RabbitMQ cluster.

However, there are also multiple references that Spring AMQP is using some failover implementation like connection reset when broker comes back to life.

I have several questions regarding this topic (given that those articles are more or less old and it's 2018 today)

  • When using Spring AMQP, is it load-balancing for still required?

  • If load-balancing is still suggested, how would I solve affinity of primary queue to its node? There would be much inter-connect between cluster nodes, because round-robin load-balancer would have 1-(1/n) success rate of hitting correct cluster node

  • Does Spring AMQP support some kind of topology awareness, which would allow it to consume from correct node?

  • There were some articles suggesting that clients should publish/consume to nodes respecting locality of queues. Does this still apply? How does this all fits together given load-balancing, Spring AMQP failover and CachingConnectionFactory?

Can anybody please provide answers to those topics and also provide relevant references, which would provide additional information for verification?

Thanks a lot

Martin Macak
  • 3,507
  • 2
  • 30
  • 54

1 Answers1

5

For each of your bullets:

  • a load balancer makes little sense with default configuration of Spring AMQP since it opens a single, long-lived, connection that is shared across all consumers. In, 2.0, you can configure the RabbitTemplate to use a separate connections; this is because it is a recommended configuration to use a different connection for publishers/consumers; this will be default in 2.1.

    • It might make sense to use a load balancer if you configure the connection factory to cache connections (instead of just channels) since, then, each component gets its own connection.
  • See next bullet.

  • See Queue Affinity and the LocalizedQueueConnectionFactory. It uses the management plugin to determine which node currently hosts the queue and connects to that. It will not work with a load balancer since it needs to connect to the actual node.

  • It is my understanding from several discussions that queue affinity is only needed in the most extreme environments and that, in most environments, the difference is immeasurable. However, environments/networks differ so much, YMMV so you may want to test. My general rule of thumb is to avoid premature optimization since the added complexity of the configuration may simply not be worth the benefit (and you may not have a problem in the first place).

Gary Russell
  • 166,535
  • 14
  • 146
  • 179
  • Thanks, your suggestion about premature optimisation using topology-aware factories is more than reasonable. I have one supplementary question though. Does CachingConnectionFactory reconnect to nodes that are once again alive? I remember some article mentioning, that it didn't connect to reconnected node. That's why LocalizedQueueConnectionFactory was suggested. Does CachingConnectionFactory support reasonable client-based load balancing? How does it connect to nodes from provided list? Is it round-robin, random or does it always connect to the first one and then to the second one as failover? – Martin Macak May 01 '18 at 06:28
  • The CCF only reconnects if the current connection is lost (or the cache is empty when using the connection cache). For this reason, it doesn't fail-back after failing over until the new connection is lost. It does not load balance, it starts from the first and proceeds down the list whenever a new connection is needed. Feel free to open an 'improvement' [JIRA Issue](https://jira.spring.io/browse/AMQP) - we could add a load balancing strategy property. In the mean time you could write an external task to shuffle the `Addresses[]` property from time-to-time. – Gary Russell May 01 '18 at 12:35
  • Yeah, that was my idea also. Thanks for all your answers – Martin Macak May 02 '18 at 07:05