Version
5.1.2
Context
An HttpClient configured with a LoadBalancer is designed to resolve all of a host's A-records and balance requests across them (HttpClientImpl: resolveAll = loadBalancer != null; OriginResolver builds an OriginServer per resolved IP, all available). In practice it connects to a single IP for a multi-homed host.
Notes
((VertxInternal) vertx).nameResolver().resolveAll("www.google.com") returns all 8 addresses, so DNS resolution is fine — the issue is downstream in the built-in origin-resolution → endpoint → selectServer path.
- Workaround: supplying an explicit
AddressResolver (e.g. AddressResolver.mappingResolver(...) with the resolved IPs) + the same LoadBalancer does round-robin across all IPs. So only the built-in (no-custom-resolver) path is affected.
Steps to reproduce
Reproducer
Vertx vertx = Vertx.vertx();
HttpClient client = vertx.httpClientBuilder()
.with(new HttpClientOptions().setProtocolVersion(HttpVersion.HTTP_1_1).setSsl(true))
.withLoadBalancer(LoadBalancer.ROUND_ROBIN) // no custom AddressResolver
.build();
Set<String> ips = ConcurrentHashMap.newKeySet();
CountDownLatch latch = new CountDownLatch(24);
for (int i = 0; i < 24; i++) {
client.request(new RequestOptions().setMethod(HttpMethod.GET)
.setHost("www.google.com").setPort(443).setURI("/").setSsl(true)) // 8 A-records
.compose(req -> req.send().compose(HttpClientResponse::body).map(b -> req.connection()))
.onComplete(ar -> { if (ar.succeeded()) ips.add(ar.result().remoteAddress().hostAddress()); latch.countDown(); });
}
latch.await(40, TimeUnit.SECONDS);
System.out.println("distinct remote IPs = " + ips.size()); // prints 1, despite 8 A-records
Expected
Requests spread across the host's resolved IPs per the policy (≈8 distinct remote IPs).
Actual
All requests hit one IP. Same with ROUND_ROBIN, RANDOM, and LEAST_REQUESTS — and RANDOM is stateless, so the load balancer is selecting among a single server; the resolved address set never reaches the selector.
Do you have a reproducer?
No response
Version
5.1.2
Context
An
HttpClientconfigured with aLoadBalanceris designed to resolve all of a host's A-records and balance requests across them (HttpClientImpl:resolveAll = loadBalancer != null;OriginResolverbuilds anOriginServerper resolved IP, allavailable). In practice it connects to a single IP for a multi-homed host.Notes
((VertxInternal) vertx).nameResolver().resolveAll("www.google.com")returns all 8 addresses, so DNS resolution is fine — the issue is downstream in the built-in origin-resolution → endpoint →selectServerpath.AddressResolver(e.g.AddressResolver.mappingResolver(...)with the resolved IPs) + the sameLoadBalancerdoes round-robin across all IPs. So only the built-in (no-custom-resolver) path is affected.Steps to reproduce
Reproducer
Expected
Requests spread across the host's resolved IPs per the policy (≈8 distinct remote IPs).
Actual
All requests hit one IP. Same with
ROUND_ROBIN,RANDOM, andLEAST_REQUESTS— andRANDOMis stateless, so the load balancer is selecting among a single server; the resolved address set never reaches the selector.Do you have a reproducer?
No response