获取java.net.UnknownHostException:主机名:使用spring-data-redis-starter时名称或服务未知

时间:2019-08-22 02:17:15

标签: java spring-boot redis spring-data-redis lettuce

我正在尝试通过使用spring-boot-starter-data-redis和生菜库并低于异常,以集群模式连接到Redis,

        2019-08-21 00:55:42.695  WARN 75 --- [ioEventLoop-6-1] i.l.c.c.topology.ClusterTopologyRefresh  : Unable to connect to myhostname.service:6379

java.util.concurrent.CompletionException: java.net.UnknownHostException: myhostname.service: Name or service not known
    at java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:292) ~[na:1.8.0_181]
    at java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:308) ~[na:1.8.0_181]
    at java.util.concurrent.CompletableFuture.uniApply(CompletableFuture.java:593) ~[na:1.8.0_181]
    at java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:577) ~[na:1.8.0_181]
    at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:474) ~[na:1.8.0_181]
    at java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:1977) ~[na:1.8.0_181]
    at io.lettuce.core.AbstractRedisClient.lambda$initializeChannelAsync$1(AbstractRedisClient.java:275) ~[lettuce-core-5.0.4.RELEASE.jar!/:na]
    at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:511) ~[netty-common-4.1.25.Final.jar!/:4.1.25.Final]
    at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:485) ~[netty-common-4.1.25.Final.jar!/:4.1.25.Final]
    at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:424) ~[netty-common-4.1.25.Final.jar!/:4.1.25.Final]
    at io.netty.util.concurrent.DefaultPromise.setFailure(DefaultPromise.java:112) ~[netty-common-4.1.25.Final.jar!/:4.1.25.Final]
    at io.netty.channel.DefaultChannelPromise.setFailure(DefaultChannelPromise.java:89) ~[netty-transport-4.1.25.Final.jar!/:4.1.25.Final]
    at io.netty.bootstrap.Bootstrap.doResolveAndConnect0(Bootstrap.java:216) ~[netty-transport-4.1.25.Final.jar!/:4.1.25.Final]
    at io.netty.bootstrap.Bootstrap.access$000(Bootstrap.java:49) ~[netty-transport-4.1.25.Final.jar!/:4.1.25.Final]
    at io.netty.bootstrap.Bootstrap$1.operationComplete(Bootstrap.java:188) ~[netty-transport-4.1.25.Final.jar!/:4.1.25.Final]
    at io.netty.bootstrap.Bootstrap$1.operationComplete(Bootstrap.java:174) ~[netty-transport-4.1.25.Final.jar!/:4.1.25.Final]
    at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:511) ~[netty-common-4.1.25.Final.jar!/:4.1.25.Final]
    at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:485) ~[netty-common-4.1.25.Final.jar!/:4.1.25.Final]
    at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:424) ~[netty-common-4.1.25.Final.jar!/:4.1.25.Final]
    at io.netty.util.concurrent.DefaultPromise.trySuccess(DefaultPromise.java:103) ~[netty-common-4.1.25.Final.jar!/:4.1.25.Final]
    at io.netty.channel.DefaultChannelPromise.trySuccess(DefaultChannelPromise.java:84) ~[netty-transport-4.1.25.Final.jar!/:4.1.25.Final]
    at io.netty.channel.AbstractChannel$AbstractUnsafe.safeSetSuccess(AbstractChannel.java:978) ~[netty-transport-4.1.25.Final.jar!/:4.1.25.Final]
    at io.netty.channel.AbstractChannel$AbstractUnsafe.register0(AbstractChannel.java:512) ~[netty-transport-4.1.25.Final.jar!/:4.1.25.Final]
    at io.netty.channel.AbstractChannel$AbstractUnsafe.access$200(AbstractChannel.java:423) ~[netty-transport-4.1.25.Final.jar!/:4.1.25.Final]
    at io.netty.channel.AbstractChannel$AbstractUnsafe$1.run(AbstractChannel.java:482) ~[netty-transport-4.1.25.Final.jar!/:4.1.25.Final]
    at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163) ~[netty-common-4.1.25.Final.jar!/:4.1.25.Final]
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404) ~[netty-common-4.1.25.Final.jar!/:4.1.25.Final]
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:465) ~[netty-transport-4.1.25.Final.jar!/:4.1.25.Final]
    at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884) ~[netty-common-4.1.25.Final.jar!/:4.1.25.Final]
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.25.Final.jar!/:4.1.25.Final]
    at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_181]
Caused by: java.net.UnknownHostException: master1.event-store-service-V-70125f6-2-1566348843-redis.service: Name or service not known
    at java.net.Inet4AddressImpl.lookupAllHostAddr(Native Method) ~[na:1.8.0_181]
    at java.net.InetAddress$2.lookupAllHostAddr(InetAddress.java:928) ~[na:1.8.0_181]
    at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1323) ~[na:1.8.0_181]
    at java.net.InetAddress.getAllByName0(InetAddress.java:1276) ~[na:1.8.0_181]
    at java.net.InetAddress.getAllByName(InetAddress.java:1192) ~[na:1.8.0_181]
    at java.net.InetAddress.getAllByName(InetAddress.java:1126) ~[na:1.8.0_181]
    at java.net.InetAddress.getByName(InetAddress.java:1076) ~[na:1.8.0_181]
    at io.netty.util.internal.SocketUtils$8.run(SocketUtils.java:146) ~[netty-common-4.1.25.Final.jar!/:4.1.25.Final]
    at io.netty.util.internal.SocketUtils$8.run(SocketUtils.java:143) ~[netty-common-4.1.25.Final.jar!/:4.1.25.Final]
    at java.security.AccessController.doPrivileged(Native Method) ~[na:1.8.0_181]
    at io.netty.util.internal.SocketUtils.addressByName(SocketUtils.java:143) ~[netty-common-4.1.25.Final.jar!/:4.1.25.Final]
    at io.netty.resolver.DefaultNameResolver.doResolve(DefaultNameResolver.java:43) ~[netty-resolver-4.1.25.Final.jar!/:4.1.25.Final]
    at io.netty.resolver.SimpleNameResolver.resolve(SimpleNameResolver.java:63) ~[netty-resolver-4.1.25.Final.jar!/:4.1.25.Final]
    at io.netty.resolver.SimpleNameResolver.resolve(SimpleNameResolver.java:55) ~[netty-resolver-4.1.25.Final.jar!/:4.1.25.Final]
    at io.netty.resolver.InetSocketAddressResolver.doResolve(InetSocketAddressResolver.java:57) ~[netty-resolver-4.1.25.Final.jar!/:4.1.25.Final]
    at io.netty.resolver.InetSocketAddressResolver.doResolve(InetSocketAddressResolver.java:32) ~[netty-resolver-4.1.25.Final.jar!/:4.1.25.Final]
    at io.netty.resolver.AbstractAddressResolver.resolve(AbstractAddressResolver.java:108) ~[netty-resolver-4.1.25.Final.jar!/:4.1.25.Final]
    at io.netty.bootstrap.Bootstrap.doResolveAndConnect0(Bootstrap.java:208) ~[netty-transport-4.1.25.Final.jar!/:4.1.25.Final]
    ... 18 common frames omitted

注意:“ myhostname.service”是由于我正在使用consul,并且可以ping myhostname.service,也可以使用“ redis-cli -c -h myhostname.service -p 6379”命令连接到它。

我连接到Redis的代码是

@Configuration
@ConfigurationProperties(prefix = "redis")
public class LettuceCacheConfig {

    private static Logger logger = LoggerFactory.getLogger(LettuceCacheConfig.class);
    private static Long topologyRefreshDuration = 10L;
    private static int maxRedirects = 3;

    private String servers;
    private String profileName; 
    private String password;

    private PoolConfig poolConfig = new PoolConfig();

    class PoolConfig {
        int maxTotal;
        int maxIdle;
        int minIdle;

        public PoolConfig() {
        }
    }

    public LettuceClientConfiguration getLettuceClientConfig() {
        final ClusterTopologyRefreshOptions options = ClusterTopologyRefreshOptions.builder()
                .enablePeriodicRefresh(Duration.of(topologyRefreshDuration, ChronoUnit.MINUTES))
                .enableAllAdaptiveRefreshTriggers().dynamicRefreshSources(true).build();

        final LettuceClientConfiguration lettuceClientConfig = LettuceClientConfiguration.builder()
                .clientOptions(ClusterClientOptions.builder().topologyRefreshOptions(options)
                        .validateClusterNodeMembership(false).build())
                .build();

        return lettuceClientConfig;
    }


    private GenericObjectPoolConfig getPoolingConfiguration() {
        final GenericObjectPoolConfig config = new GenericObjectPoolConfig();
        config.setMaxIdle(this.poolConfig.getMaxIdle());
        config.setMaxTotal(this.poolConfig.getMaxTotal());
        config.setMinIdle(this.poolConfig.getMinIdle());
        return config;
    }

    public RedisClusterConfiguration getClusterConfiguration() {
        final RedisClusterConfiguration clusterConfiguration = new RedisClusterConfiguration();//new RedisClusterConfiguration(getRedisServers());
        String hostPort = getRedisServers().get(0);
        String tokens[] = hostPort.split(":");
        logger.info("REDIS HOST IS {}", tokens[0]);
        logger.info("REDIS PORT IS {}", tokens[1]);
        clusterConfiguration.clusterNode(tokens[0], Integer.parseInt(tokens[1]));
        clusterConfiguration.setMaxRedirects(maxRedirects);
        logger.info("PASSWORD is {}",password);
        clusterConfiguration.setPassword(RedisPassword.of(password));
        return clusterConfiguration;
    }



    private List<String> getRedisServers() {
        String tokens[] = servers.split(",");
        logger.debug("Redis Servers are {}", Arrays.toString(tokens));
        return Arrays.asList(tokens);
    }

    @Bean
    public RedisConnectionFactory getLettuceConnectionFactory() {
        return new LettuceConnectionFactory(getClusterConfiguration(),
         getLettuceClientConfig());
    }

}

因为我在java.net.InetAddress.getByName(“ hostname”)遇到异常,所以

  1. 从我的应用程序容器运行redis-cli以连接到redis集群容器成功。(如上所述)

  2. 因为我在java.net.InetAddress.getByName(“ hostname”)处遇到异常,所以我使用Redis主机名从我的应用容器内部尝试了相同的方法。它成功并且没有引发UnknownHostException。

  3. 从应用容器ping通到redis主机。

  4. 我确实在本地计算机上设置了redis-cluster,它可以与上面的代码一起正常工作,只有更改是我提供了127.0.0.1:6379而不是hostname.service:6379。

我正在使用spring-boot-starter-parent:2.0.3.RELEASE和lettuce-core:5.0.4。代码有问题吗?

1 个答案:

答案 0 :(得分:0)

我不能说这完全回答了这个问题,但是找到了问题的原因。问题是应用容器启动时,redis容器/服务仍未在领事馆注册,因此查找名称为“ master1.redis.service”的redis容器会返回UnknownHostException。但是,由于我运行redis-cli并在一段时间后执行ping操作,所以没有连接问题。我通过重新启动应用程序容器(同时保持Redis容器处于启动状态)验证了这一点,然后没有UnknownHostException。我不知道的原因是,如果最初是否存在UnknowHostException,为什么ClusterTopologyRefreshOptions不起作用?按照我的想法,它应该在一段时间后再次查询主机名,并从领事那里获得解析/ ip。但这没有发生