[SpringCloud-Eureka] zookeeper和Eureka使用IP注册

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/my_momo_csdn/article/details/82190560

一.注册IP而不是服务名称

1.1 问题 : 在使用Eureka和Zookeeper作为注册中心的时候,均是默认注册主机名称,但是很多时候主机名称解析会有问题,通过配置使用IP注册:

Eureka:
 eureka.instance.prefer-ip-address = true
Zookeeper:
zookeeper中的配置很隐蔽,查了很久,配置形式如下:
spring.cloud.zookeeper.discovery.instance-host=${spring.cloud.client.ipAddress}
这里右边可以写成IP,但是写成IP不好,比如使用配置中心多实例共享一份配置就有问题,因此写成这样,会
动态获取实例运行的主机的ip。配置后,就可以将IP注册到zookeeper,其他服务使用Feign调用就不会有问题了。

二.Eureka注册IP解读

2.1 配置注册IP

通过eureka.instance.prefer-ip-address = true配置,将微服务的IP注册到Eureka,而不是主机名称
代码解析如下:
在org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean类的getHostName方法中:
        @Override
	public String getHostName(boolean refresh) {
		if (refresh && !this.hostInfo.override) {
			this.ipAddress = this.hostInfo.getIpAddress();
			this.hostname = this.hostInfo.getHostname();
		}
		return this.preferIpAddress ? this.ipAddress : this.hostname;
	}
	这里可以看到最后返回时通过preferIpAddress配置项来决定返回的是IP还是主机名称,如下所示,默认是false,
	也就是默认注册的是this.hostname主机名称:
	/**
	 * Flag to say that, when guessing a hostname, the IP address of the server should be
	 * used in prference to the hostname reported by the OS.
	 */
	private boolean preferIpAddress = false;
  • 总言之:eureka.instance.prefer-ip-address = true通过该配置项可以往Eureka注册IP而不是主机名(默认是主机名称);

2.2 配置自定义IP

配置项spring.cloud.client.ipAddress可指定一个IP,如果指定了IP同时开启eureka.instance.prefer-ip-address=true
的话,那么会注册哪一个信息呢?我们跟进if (refresh && !this.hostInfo.override) 这个判断条件,refresh如果为false则
直接走下面的return返回不会再去执行两个get方法(可以理解为不去重新获取,即不refresh刷新),那么条件取决于
HostInfo的override属性,跟进:根据setIpAddress方法我们看到,当设置了eureka.instance.ipAddress时,override
会设置为true,,那么在执行上面的逻辑的时候,就不会再执行hostInfo的getIpAddress和getHostname方法了,因此
就会直接返回this.ipAddress,而这个ipAddress就是spring.cloud.client.ipAddress指定的。
	public void setIpAddress(String ipAddress) {
		this.ipAddress = ipAddress;
		this.hostInfo.override = true;
	}
  • 总言之:配置了eureka.instance.prefer-ip-address = true和spring.cloud.client.ipAddress的情况下,会注册spring.cloud.client.ipAddress指定的IP,而不会通过findFirstNonLoopbackHostInfo方法去寻找本机的非回环地址;

3.findFirstNonLoopbackAddress方法

下面是简单改造过的findFirstNonLoopbackAddress方法,通过该方法可以获取本机的非回环IP地址

public InetAddress findFirstNonLoopbackAddress() {
        InetAddress result = null;
        try {
            int lowest = Integer.MAX_VALUE;
            for (Enumeration<NetworkInterface> nics = NetworkInterface
                    .getNetworkInterfaces(); nics.hasMoreElements();) {
                NetworkInterface ifc = nics.nextElement();
                if (ifc.isUp()) {
                    log.trace("Testing interface: " + ifc.getDisplayName());
                    if (ifc.getIndex() < lowest || result == null) {
                        lowest = ifc.getIndex();
                    }
                    else if (result != null) {
                        continue;
                    }

                    // @formatter:off

                        for (Enumeration<InetAddress> addrs = ifc
                                .getInetAddresses(); addrs.hasMoreElements();) {
                            InetAddress address = addrs.nextElement();
                            if (address instanceof Inet4Address
                                    && !address.isLoopbackAddress()
                                   ) {
                                log.trace("Found non-loopback interface: "
                                        + ifc.getDisplayName());
                                result = address;
                            }
                        }
                    }
                    // @formatter:on
                }

        }
        catch (IOException ex) {
            log.error("Cannot get first non-loopback address", ex);
        }

        if (result != null) {
            return result;
        }

        try {
            return InetAddress.getLocalHost();
        }
        catch (UnknownHostException e) {
            log.warn("Unable to retrieve localhost");
        }

        return null;
    }

猜你喜欢

转载自blog.csdn.net/my_momo_csdn/article/details/82190560