springcloud如何获取hostname和ip

多个ip到底用哪个?

上次说到instanceinfo的hostname,ip,那么这些值是从哪来的呢?

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

可以看到是从InetUtils类获取的,而这个类是从InetUtilsProperties获取数据
及从配置文件spring.cloud.inetutils开头的配置获取。

你可以设置忽略的网卡,或者优先选择的网卡,这两个设置都支持正则

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

如果这两个设置你都不满意,你可以设置忽略值为.*,忽略所有网卡

然后用hostname从/etc/hosts中获取ip,也就是说你要在/etc/hosts设置你的ip对应的本机hostname

如果你认为这样就完事了,那就是大错特错。

通过查找InetUtils.findFirstNonLoopbackAddress引用发现,在HostInfoEnvironmentPostProcessor类中,并未使用配置文件的参数,而是直接创建了一个对象。

@Override
    public void postProcessEnvironment(ConfigurableEnvironment environment,
            SpringApplication application) {
        InetUtils.HostInfo hostInfo = getFirstNonLoopbackHostInfo(environment);
        LinkedHashMap map = new LinkedHashMap<>();
        map.put("spring.cloud.client.hostname", hostInfo.getHostname());
        map.put("spring.cloud.client.ip-address", hostInfo.getIpAddress());
        MapPropertySource propertySource = new MapPropertySource(
                "springCloudClientHostInfo", map);
        environment.getPropertySources().addLast(propertySource);
    }

    private HostInfo getFirstNonLoopbackHostInfo(ConfigurableEnvironment environment) {
        InetUtilsProperties target = new InetUtilsProperties();
        ConfigurationPropertySources.attach(environment);
        Binder.get(environment).bind(InetUtilsProperties.PREFIX,
                Bindable.ofInstance(target));
        try (InetUtils utils = new InetUtils(target)) {
            return utils.findFirstNonLoopbackHostInfo();
        }
    }

虽然是new了一个对象,但是其实使用了environment设置了属性,那么我们有两种方案。

  1. 在启动参数中传入参数,比如--spring.cloud.inetutils.ignoredInterfaces=.*
  2. 创建一个EnvironmentPostProcessor类,并且该类的order要比HostInfoEnvironmentPostProcessor小,及优先加载我们定义的
public class InspectEurekaClientIp implements BeanPostProcessor, EnvironmentPostProcessor, Ordered {
    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        Map ignoredInterfaces = Maps.newHashMap();
        ignoredInterfaces.put("spring.cloud.inetutils.ignoredInterfaces", Lists.newArrayList(".*"));
        SystemEnvironmentPropertySource systemEnvironmentPropertySource = new SystemEnvironmentPropertySource("systemEnvironment", ignoredInterfaces);
        environment.getPropertySources().addLast(systemEnvironmentPropertySource);

    }

    @Override
    public int getOrder() {
        return ConfigFileApplicationListener.DEFAULT_ORDER - 2;
    }
}

还要创建META-INF/spring.factories文件

org.springframework.boot.env.EnvironmentPostProcessor=\
上述类名

你可能感兴趣的:(springcloud如何获取hostname和ip)