Skip to content

Commit

Permalink
Resolve hostnames using netty's DNS resolver #498
Browse files Browse the repository at this point in the history
Lettuce now defaults to netty's DNS resolution upon connect when using netty 4.1. DnsResolver returns an empty array of addresses to signal an unresolved address. Netty performs a non-blocking DNS lookup.
  • Loading branch information
mp911de committed Apr 1, 2017
1 parent 1a66681 commit 3c8d021
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@

import io.netty.util.HashedWheelTimer;
import io.netty.util.Timer;
import io.netty.util.Version;
import io.netty.util.concurrent.*;
import io.netty.util.internal.SystemPropertyUtil;
import io.netty.util.internal.logging.InternalLogger;
Expand Down Expand Up @@ -87,6 +88,8 @@ public class DefaultClientResources implements ClientResources {
*/
public static final Supplier<Delay> DEFAULT_RECONNECT_DELAY = Delay::exponential;

private static final boolean NETTY_DNS_RESOLVER_SUPPORTED;

static {
int threads = Math.max(
1,
Expand All @@ -98,6 +101,9 @@ public class DefaultClientResources implements ClientResources {
if (logger.isDebugEnabled()) {
logger.debug("-Dio.netty.eventLoopThreads: {}", threads);
}

Version version = Version.identify().get("netty-common");
NETTY_DNS_RESOLVER_SUPPORTED = version != null && version.artifactVersion().startsWith("4.1");
}

private final boolean sharedEventLoopGroupProvider;
Expand Down Expand Up @@ -195,7 +201,7 @@ protected DefaultClientResources(Builder builder) {
}

if (builder.dnsResolver == null) {
dnsResolver = DnsResolvers.JVM_DEFAULT;
dnsResolver = NETTY_DNS_RESOLVER_SUPPORTED ? DnsResolvers.UNRESOLVED : DnsResolvers.JVM_DEFAULT;
} else {
dnsResolver = builder.dnsResolver;
}
Expand Down Expand Up @@ -235,7 +241,7 @@ public static class Builder {
private CommandLatencyCollectorOptions commandLatencyCollectorOptions = DefaultCommandLatencyCollectorOptions.create();
private CommandLatencyCollector commandLatencyCollector;
private EventPublisherOptions commandLatencyPublisherOptions = DefaultEventPublisherOptions.create();
private DnsResolver dnsResolver = DnsResolvers.JVM_DEFAULT;
private DnsResolver dnsResolver = NETTY_DNS_RESOLVER_SUPPORTED ? DnsResolvers.UNRESOLVED : DnsResolvers.JVM_DEFAULT;
private Supplier<Delay> reconnectDelay = DEFAULT_RECONNECT_DELAY;

private Builder() {
Expand Down
10 changes: 6 additions & 4 deletions src/main/java/com/lambdaworks/redis/resource/DnsResolver.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2011-2016 the original author or authors.
* Copyright 2011-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -20,17 +20,19 @@

/**
* Users may implement this interface to override the normal DNS lookup offered by the OS.
*
*
* @author Mark Paluch
* @since 4.2
*/
public interface DnsResolver {

/**
* Returns the IP address for the specified host name.
*
*
* @param host the hostname, must not be empty or {@literal null}.
* @return array of one or more {@link InetAddress adresses}
* @return array of one or more {@link InetAddress adresses}. An empty array indicates that DNS resolution is not supported
* by this {@link DnsResolver} and should happen by netty, see
* {@link java.net.InetSocketAddress#createUnresolved(String, int)}.
* @throws UnknownHostException if the given host is not recognized or the associated IP address cannot be used to build an
* {@link InetAddress} instance
*/
Expand Down
29 changes: 21 additions & 8 deletions src/main/java/com/lambdaworks/redis/resource/DnsResolvers.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2011-2016 the original author or authors.
* Copyright 2011-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -19,9 +19,8 @@
import java.net.UnknownHostException;

/**
*
* Predefined DNS resolvers.
*
*
* @author Mark Paluch
* @since 4.2
*/
Expand All @@ -30,10 +29,24 @@ public enum DnsResolvers implements DnsResolver {
/**
* Java VM default resolver.
*/
JVM_DEFAULT;
JVM_DEFAULT {
@Override
public InetAddress[] resolve(String host) throws UnknownHostException {
return InetAddress.getAllByName(host);
}
},

/**
* Non-resolving {@link DnsResolver}. Returns an empty {@link InetAddress} to indicate an unresolved address.
*
* @see java.net.InetSocketAddress#createUnresolved(String, int)
* @since 4.4
*/
UNRESOLVED {
@Override
public InetAddress[] resolve(String host) throws UnknownHostException {
return new InetAddress[0];
}
};

@Override
public InetAddress[] resolve(String host) throws UnknownHostException {
return InetAddress.getAllByName(host);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2011-2016 the original author or authors.
* Copyright 2011-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -24,14 +24,14 @@

/**
* Resolves a {@link com.lambdaworks.redis.RedisURI} to a {@link java.net.SocketAddress}.
*
*
* @author Mark Paluch
*/
public class SocketAddressResolver {

/**
* Resolves a {@link com.lambdaworks.redis.RedisURI} to a {@link java.net.SocketAddress}.
*
*
* @param redisURI must not be {@literal null}
* @param dnsResolver must not be {@literal null}
* @return the resolved {@link SocketAddress}
Expand All @@ -43,8 +43,13 @@ public static SocketAddress resolve(RedisURI redisURI, DnsResolver dnsResolver)
}

try {
InetAddress inetAddress = dnsResolver.resolve(redisURI.getHost())[0];
return new InetSocketAddress(inetAddress, redisURI.getPort());
InetAddress[] inetAddress = dnsResolver.resolve(redisURI.getHost());

if (inetAddress.length == 0) {
return InetSocketAddress.createUnresolved(redisURI.getHost(), redisURI.getPort());
}

return new InetSocketAddress(inetAddress[0], redisURI.getPort());
} catch (UnknownHostException e) {
return redisURI.getResolvedAddress();
}
Expand Down

0 comments on commit 3c8d021

Please sign in to comment.