侧边栏壁纸
  • 累计撰写 29 篇文章
  • 累计创建 18 个标签
  • 累计收到 2 条评论

目 录CONTENT

文章目录

docker安装后引起dubbo注册到nacos的ip出现问题

bsdlzg
2022-11-15 / 0 评论 / 3 点赞 / 304 阅读 / 662 字

问题描述

  线上服务器安装docker后,出现多的网卡,导致dubbo注册的时候,现在ip的不正确的情况
docker安装后引起dubbo注册到nacos的ip出现问题

问题查找

  原因是因为我在安装完docker后,服务器机器上配置了很多的虚拟IP,这样错误的解析结果导致dubbo服务一直无法被访问到,调用方一直在报错。

  造成这种结果的原因是什么呢?既然是注册的ip有问题,那么我们可以先看下dubbo解析IP地址的源码,ServiceConfig类下的doExportUrlsFor1Protocol方法:

private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List<URL> registryURLs) {
      ...................省略......................

        //1.先从ProtocolConfig中获取host
        String host = protocolConfig.getHost();
        //2.如果host为空,再从ProviderConfig中获取host
        if (provider != null && (host == null || host.length() == 0)) {
            host = provider.getHost();
        }
        boolean anyhost = false;
        //3.验证host是否为本地可用的host,如果是本地host(0.0.0.0或者localhost或者127.0.0.1之类)则继续解析
        if (NetUtils.isInvalidLocalHost(host)) {
            anyhost = true;
            try {
                //4.通过InetAddress的方式获取host,默认读取本机hosts中hostname对应的ip地址
                host = InetAddress.getLocalHost().getHostAddress();
            } catch (UnknownHostException e) {
                logger.warn(e.getMessage(), e);
            }
            if (NetUtils.isInvalidLocalHost(host)) {
                if (registryURLs != null && registryURLs.size() > 0) {
                    for (URL registryURL : registryURLs) {
                        try {
                            Socket socket = new Socket();
                            try {
                                //5.通过SocketAddress的方式获取host,一般情况下解析到此处就可以得到正确的本地ip,但是因为我配置了很多虚拟ip,所以这里导致了解析异常
                                SocketAddress addr = new InetSocketAddress(registryURL.getHost(), registryURL.getPort());
                                socket.connect(addr, 1000);
                                host = socket.getLocalAddress().getHostAddress();
                                break;
                            } finally {
                                try {
                                    socket.close();
                                } catch (Throwable e) {}
                            }
                        } catch (Exception e) {
                            logger.warn(e.getMessage(), e);
                        }
                    }
                }
                //6.遍历本地网卡,返回一个合理的host 
                if (NetUtils.isInvalidLocalHost(host)) {
                    host = NetUtils.getLocalHost();
                }
            }
        }
..............省略..............
}

  dubbo解析IP地址的步骤如下:

  1. 先从ProtocolConfig中取host
  2. 再从ProviderConfig中取host
  3. 若取出的是本地host, 则继续取host
  4. 通过InetAddress.getLocalHost().getHostAddress();的方式获取Host
  5. 通过Socket的方式尝试连接到注册中心,通过socket.getLocalAddress().getHostAddress()获取Host
  6. 遍历本地网卡, 返回第一个合理的Host

解决方法

  1. 配置本机主机名,在hosts中加入本机名和本机物理ip的映射关系(最简单,不用动任何配置)

  2. 如果是docker启动相关应用,可以在run时,加入-e DUBBO_IP_TO_REGISTRY = ip地址

  3. jar方式启动程序,添加启动参数-D DUBBO_IP_TO_REGISTRY = ip地址

备注: 在2、3的方式中,其实原理都是类似,都是通过配置参数将ip设置成我们想要设置的ip地址

3

评论区