Eureka注册中心ip-Address参数详解

Eureka注册中心ip-Address参数详解

在Eureka中如果不指定任何的Ip参数的话,那么提供者注册到Eureka中,消费者进行消费的时候访问的Ip为部署Eureka服务器的Ip地址。

Eureka注册中心ip-Address参数详解_第1张图片

Eureka不加参数调用图

那么正常情况下,服务器A调用将会调到服务B的身上,而此时如果在服务B中加入了一下的参数。那么就变了

eureka.instance.prefer-ip-address=true
eureka.instance.ip-address=172.12.9.0

此时服务C和服务B是相同的服务,部署在不同的服务器中,Ip地址不同,那么此时调用的服务将会被Eureka转发到服务C中。

Eureka注册中心ip-Address参数详解_第2张图片

image

源代码详解

我们可以在EurekaClientAutoConfiguration类中找到eurekaInstanceConfigBean方法。发现他在程序启动的时候就会加载一些eureka的配置信息

@Bean
    @ConditionalOnMissingBean(value = EurekaInstanceConfig.class, search = SearchStrategy.CURRENT)
    public EurekaInstanceConfigBean eurekaInstanceConfigBean(InetUtils inetUtils,
                                                             ManagementMetadataProvider managementMetadataProvider, ConfigurableEnvironment env) throws MalformedURLException {
        PropertyResolver environmentPropertyResolver = new RelaxedPropertyResolver(env);
        PropertyResolver eurekaPropertyResolver = new RelaxedPropertyResolver(env, "eureka.instance.");
        String hostname = eurekaPropertyResolver.getProperty("hostname");

        boolean preferIpAddress = Boolean.parseBoolean(eurekaPropertyResolver.getProperty("preferIpAddress"));
        String ipAddress = eurekaPropertyResolver.getProperty("ipAddress");
        boolean isSecurePortEnabled = Boolean.parseBoolean(eurekaPropertyResolver.getProperty("securePortEnabled"));
        String serverContextPath = environmentPropertyResolver.getProperty("server.contextPath", "/");
        int serverPort = Integer.valueOf(environmentPropertyResolver.getProperty("server.port", environmentPropertyResolver.getProperty("port", "8080")));

        Integer managementPort = environmentPropertyResolver.getProperty("management.port", Integer.class);// nullable. should be wrapped into optional
        String managementContextPath = environmentPropertyResolver.getProperty("management.contextPath");// nullable. should be wrapped into optional
        Integer jmxPort = environmentPropertyResolver.getProperty("com.sun.management.jmxremote.port", Integer.class);//nullable
        EurekaInstanceConfigBean instance = new EurekaInstanceConfigBean(inetUtils);

        instance.setNonSecurePort(serverPort);
        instance.setInstanceId(getDefaultInstanceId(environmentPropertyResolver));
        instance.setPreferIpAddress(preferIpAddress);
        instance.setSecurePortEnabled(isSecurePortEnabled);
        if (StringUtils.hasText(ipAddress)) {
            instance.setIpAddress(ipAddress);
        }

        if(isSecurePortEnabled) {
            instance.setSecurePort(serverPort);
        }

        if (StringUtils.hasText(hostname)) {
            instance.setHostname(hostname);
        }
        String statusPageUrlPath = eurekaPropertyResolver.getProperty("statusPageUrlPath");
        String healthCheckUrlPath = eurekaPropertyResolver.getProperty("healthCheckUrlPath");

        if (StringUtils.hasText(statusPageUrlPath)) {
            instance.setStatusPageUrlPath(statusPageUrlPath);
        }
        if (StringUtils.hasText(healthCheckUrlPath)) {
            instance.setHealthCheckUrlPath(healthCheckUrlPath);
        }

        ManagementMetadata metadata = managementMetadataProvider.get(instance, serverPort,
                serverContextPath, managementContextPath, managementPort);

        if(metadata != null) {
            instance.setStatusPageUrl(metadata.getStatusPageUrl());
            instance.setHealthCheckUrl(metadata.getHealthCheckUrl());
            if(instance.isSecurePortEnabled()) {
                instance.setSecureHealthCheckUrl(metadata.getSecureHealthCheckUrl());
            }
            Map metadataMap = instance.getMetadataMap();
            if (metadataMap.get("management.port") == null) {
                metadataMap.put("management.port", String.valueOf(metadata.getManagementPort()));
            }
        }

        setupJmxPort(instance, jmxPort);
        return instance;
    }

此时我们看到String ipAddress = eurekaPropertyResolver.getProperty("ipAddress");就是在这进行设置的,此时如果没有设置eureka.instance.ip-address参数的时候,那么此ipAddress就是本机的Ip。这是如何设置的呢?我们可以看到代码中有这么一句

EurekaInstanceConfigBean instance = new EurekaInstanceConfigBean(inetUtils);
instance.setNonSecurePort(serverPort);
instance.setInstanceId(getDefaultInstanceId(environmentPropertyResolver));
instance.setPreferIpAddress(preferIpAddress);
instance.setSecurePortEnabled(isSecurePortEnabled);
if (StringUtils.hasText(ipAddress)) {
    instance.setIpAddress(ipAddress);
}

EurekaInstanceConfigBean先进行了初始化,我们进入EurekaInstanceConfigBean的构造参数中看

    public EurekaInstanceConfigBean(InetUtils inetUtils) {
        this.inetUtils = inetUtils;
        this.hostInfo = this.inetUtils.findFirstNonLoopbackHostInfo();
        this.ipAddress = this.hostInfo.getIpAddress();
        this.hostname = this.hostInfo.getHostname();
    }

可以看到在这进行了初始化ipAddress参数,其中hostInfo是如何得到的就进行讲解了,其本质就是为了获取本机的真实IP。到这给Eureka注册中心的注册信息已经准备好了

然后在InstanceInfoReplicator中调用run方法进行将自己信息注册到远程的Eureka中。

此时就可以看到如果设置eureka.instance.prefer-ip-address为false时,那么注册到Eureka中的Ip地址就是本机的Ip地址。如果设置了true并且也设置了eureka.instance.ip-address那么就将此ip地址注册到Eureka中。那么调用的时候,发送的请求目的地就是此Ip地址。



转自:不学无数的程序员
链接:https://www.jianshu.com/p/886947b52cb4

 

你可能感兴趣的:(Spring,Cloud)