Dubbo 获取本地ip错误

前言

我们因为安全漏洞将dubbo 升级到2.7.15 版本,当环境中存在docker 部署的时候。dubbo 获取本机ip将会变成docker0的地址。

实践

我们查看dubbo 获取ip地址的源码org.apache.dubbo.common.utils.NetUtils#getLocalAddress0来获取本地地址。
可以看到关键在于findNetworkInterface() 获取到网卡的地址
在这里插入图片描述
我们将findNetworkInterface 这个方法贴出来,看到要获取networkInterface 分了三步,

public static NetworkInterface findNetworkInterface() {

        List<NetworkInterface> validNetworkInterfaces = emptyList();
        try {
            validNetworkInterfaces = getValidNetworkInterfaces();
        } catch (Throwable e) {
            logger.warn(e);
        }

        NetworkInterface result = null;

        // Try to find the preferred one
        //一、查看所有网卡中是否isPreferredNetworkInterface(networkInterface) 是否优先网卡
        //判断是否有是优先网卡通过名字来比对的
        //String preferredNetworkInterface = System.getProperty(DUBBO_PREFERRED_NETWORK_INTERFACE);
       // return Objects.equals(networkInterface.getDisplayName(), preferredNetworkInterface);
        for (NetworkInterface networkInterface : validNetworkInterfaces) {
            if (isPreferredNetworkInterface(networkInterface)) {
                result = networkInterface;
                break;
            }
        }

        if (result == null) { // If not found, try to get the first one
            for (NetworkInterface networkInterface : validNetworkInterfaces) {
                Enumeration<InetAddress> addresses = networkInterface.getInetAddresses();
                while (addresses.hasMoreElements()) {
                    Optional<InetAddress> addressOp = toValidAddress(addresses.nextElement());
                    if (addressOp.isPresent()) {
                        try {
                            if (addressOp.get().isReachable(100)) {
                                return networkInterface;
                            }
                        } catch (IOException e) {
                            // ignore
                        }
                    }
                }
            }
        }

        if (result == null) {
            result = first(validNetworkInterfaces);
        }

        return result;
    }

    public static String getHostName(String address) {
        try {
            int i = address.indexOf(':');
            if (i > -1) {
                address = address.substring(0, i);
            }
            String hostname = HOST_NAME_CACHE.get(address);
            if (hostname != null && hostname.length() > 0) {
                return hostname;
            }
            InetAddress inetAddress = InetAddress.getByName(address);
            if (inetAddress != null) {
                hostname = inetAddress.getHostName();
                HOST_NAME_CACHE.put(address, hostname);
                return hostname;
            }
        } catch (Throwable e) {
            // ignore
        }
        return address;
    }

一、查看所有网卡中是否isPreferredNetworkInterface(networkInterface) 是否优先网卡
判断是否有是优先网卡通过名字来比对的

二、没有配置优先网卡或者配置优先网卡不存在则会
获取到当0.1s网络可达的网卡

三、如果前面条件都不成功
直接获取i存在的网卡

根据上面三个判断条件如果获取网卡不是自己想要的,可以通过配置优先网卡来获取自己想要网卡。

String preferredNetworkInterface = System.getProperty(DUBBO_PREFERRED_NETWORK_INTERFACE);
return Objects.equals(networkInterface.getDisplayName(), preferredNetworkInterface);

DUBBO_PREFERRED_NETWORK_INTERFACE 的值是dubbo.network.interface.preferred
那么就可以在启动命令中或者yml配置网卡名称

-Ddubbo.network.interface.preferred=eth0 (启动命令中添加)

yml配置优先网卡名称:

dubbo:
network:
interface:
preferred: eth0

同时也可以通过排除忽略网卡排除错误网卡
-Ddubbo.network.interface.ignored=docker0

yml配置优先网卡名称:

dubbo:
network:
interface:
ignored: docker0

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值