Spring AMQP connecting to cluster with LB DNS - use single or multiple addresses?

61 Views Asked by At

My code will try to connect to an CloudAMQP 3-node cluster, which provides 2 flavours of DNS names:

  1. A record that returns 3 IP addresses.
  2. Three records that returns each of the underlying IP address. Example:
PS C:\Users\LiuSean> nslookup funny-plum-koala.rmq2.cloudamqp.com
...

Non-authoritative answer:
Name:    funny-plum-koala.rmq2.cloudamqp.com
Addresses:  3.218.133.71
          34.231.176.151
          44.192.12.180

PS C:\Users\LiuSean> nslookup funny-plum-koala-02.rmq2.cloudamqp.com
...

Non-authoritative answer:
Name:    funny-plum-koala-02.rmq2.cloudamqp.com
Address:  3.218.133.71

PS C:\Users\LiuSean> nslookup funny-plum-koala-03.rmq2.cloudamqp.com
...

Non-authoritative answer:
Name:    funny-plum-koala-03.rmq2.cloudamqp.com
Address:  34.231.176.151

Per Spring AMQP document https://docs.spring.io/spring-amqp/reference/html/#cluster, it seems that the preferred way is to use the individual names:

@Bean
public CachingConnectionFactory ccf() {
   CachingConnectionFactory ccf = new CachingConnectionFactory();
   ccf.setAddresses("host1:5672,host2:5672,host3:5672");
   return ccf;
}

But does this offer benefits over using the single DNS records that returns 3 addresses? I've done my share of searching but there doesn't seem to be a definitive answer.

I've tested with containers with 3 addresses and it seems to work:

ccf.setAddresses("host1:5672,host2:5672,host3:5672");

However it'll be a lot of work to set up a separate DNS server to return 3 addresses to test.

1

There are 1 best solutions below

8
Artem Bilan On BEST ANSWER

The CachingConnectionFactory exposes an setAddressResolver(AddressResolver) option:

/**
 * Set an {@link AddressResolver} to use when creating connections; overrides
 * {@link #setAddresses(String)}, {@link #setHost(String)}, and {@link #setPort(int)}.
 * @param addressResolver the resolver.
 * @since 2.1.15
 */
public void setAddressResolver(AddressResolver addressResolver) {

One of the impl is probably what you are looking for:

/**
 * {@link AddressResolver} that resolves DNS record IPs.
 * Uses {@link InetAddress} internally.
 * The first returned address is used when automatic recovery is NOT enabled
 * at the {@link ConnectionFactory} level.
 * When automatic recovery is enabled, a random address will be picked up
 * from the returned list of {@link Address}es.
 */
public class DnsRecordIpAddressResolver implements AddressResolver {

It does this internally InetAddress.getAllByName(hostName);

From docs: https://docs.spring.io/spring-amqp/reference/html/#addressresolver