美文网首页
dubbo注册服务IP解析异常及IP解析源码分析

dubbo注册服务IP解析异常及IP解析源码分析

作者: 蹩脚的小三 | 来源:发表于2019-03-12 13:59 被阅读0次

    在使用dubbo注册服务时会遇到IP解析错误导致无法正常访问.

    比如: 本机设置的IP为172.16.11.111, 但实际解析出来的是180.20.174.11

    这样就导致这个Service永远也无法被访问到, 而调用方一直报错.

    当然若发现服务无法访问, 最好先通过dubbo-admin后台排查下注册的服务是否正常.

    IP解析异常时的解决方法:

    绑定hostname+ip

    1. 先查看机器的hostname2. 修改hosts文件, 增加hostname 172.16.11.111

    配置nameserver

    排查机器上配置的nameserver是否有问题, 若存在无用的nameserver则直接删掉

    在dubbo的配置文件中写死host

    <dubbo:protocol host="172.16.11.111"/>

    或者在每个provider中绑定host

    <dubbo:provider host="172.16.11.111">

    最好不要用第三种方式, 限制太多. 而且如果这样做了就不支持集群了.

    dubbo的官网也不建议使用这种方式. 请慎用.

    dubbo获取IP源码分析

        /**

        * 判断host是否为不可用的本地Host

        */    public static boolean isInvalidLocalHost(String host) {

            return host == null

                        || host.length() == 0                    || host.equalsIgnoreCase("localhost")

                        || host.equals("0.0.0.0")

                        || (LOCAL_IP_PATTERN.matcher(host).matches());

        }

        /**

        * 获取本地Host.

        * 若address == null ? "127.0.0.1" : InetAddress.getHostAddress();

        */    public static String getLocalHost(){

            InetAddress address = getLocalAddress();

            return address == null ? LOCALHOST : address.getHostAddress();

        }

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

            ...

            ...

            //1. 先从ProtocolConfig中取host. 若没有配置则为null        String host = protocolConfig.getHost();

            //2. 再从ProviderConfig中取host. 若没有配置则为null        if (provider != null && (host == null || host.length() == 0)) {

                host = provider.getHost();

            }

            boolean anyhost = false;

            //3. 若取出的是本地host, 则继续取host        if (NetUtils.isInvalidLocalHost(host)) {

                anyhost = true;

                try {

                    //4. 通过InetAddress的方式获取Host                //默认读取本机hosts中hostname对应的IP                //如: 你在hosts中配置了 leo 172.16.11.111                //则读取的IP就是172.16.11.111                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. 通过Socket的方式获取Host                                //一般解析到这里, 都会获取到正确的本地IP, 除非你有多网卡, 或者有VPN, 导致无法正常解析.                                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                //最后一个大招. 当上述都解析不到时, 则会遍历本地网卡.                //逐个获取IP, 直到有一个合理的IP为止.                if (NetUtils.isInvalidLocalHost(host)) {

                        host = NetUtils.getLocalHost();

                    }

                }

            }

            ...

        }

    /**

        * 遍历本地网卡,返回第一个合理的IP。

        * @return 本地网卡IP

        */    public static InetAddress getLocalAddress() {

            if (LOCAL_ADDRESS != null)

                return LOCAL_ADDRESS;

            InetAddress localAddress = getLocalAddress0();

            LOCAL_ADDRESS = localAddress;

            return localAddress;

        }

        /**

        * 遍历本地网卡,返回第一个合理的IP。

        * @return 本地网卡IP

        */    private static InetAddress getLocalAddress0() {

            InetAddress localAddress = null;

            try {

                localAddress = InetAddress.getLocalHost();

                if (isValidAddress(localAddress)) {

                    return localAddress;

                }

            } catch (Throwable e) {

                logger.warn("Failed to retriving ip address, " + e.getMessage(), e);

            }

            try {

                Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();

                if (interfaces != null) {

                    while (interfaces.hasMoreElements()) {

                        try {

                            NetworkInterface network = interfaces.nextElement();

                            Enumeration<InetAddress> addresses = network.getInetAddresses();

                            if (addresses != null) {

                                while (addresses.hasMoreElements()) {

                                    try {

                                        InetAddress address = addresses.nextElement();

                                        if (isValidAddress(address)) {

                                            return address;

                                        }

                                    } catch (Throwable e) {

                                        logger.warn("Failed to retriving ip address, " + e.getMessage(), e);

                                    }

                                }

                            }

                        } catch (Throwable e) {

                            logger.warn("Failed to retriving ip address, " + e.getMessage(), e);

                        }

                    }

                }

            } catch (Throwable e) {

                logger.warn("Failed to retriving ip address, " + e.getMessage(), e);

            }

            logger.error("Could not get local host ip address, will use 127.0.0.1 instead.");

            return localAddress;

        }

    相关文章

      网友评论

          本文标题:dubbo注册服务IP解析异常及IP解析源码分析

          本文链接:https://www.haomeiwen.com/subject/cndbpqtx.html