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

来源:互联网 发布:淘宝扣分12分会怎么样 编辑:程序博客网 时间:2024/04/30 13:49

在使用dubbo注册服务时会遇到IP解析错误导致无法正常访问.
比如: 本机设置的IP为172.16.11.111, 但实际解析出来的是180.20.174.11
这样就导致这个Service永远也无法被访问到, 而调用方一直报错.

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

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

  • 绑定hostname+ip
    1. 先查看机器的hostname    2. 修改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;    }
0 0
原创粉丝点击