阅读本文你将了解

  • 微服务注册到Eureka Server上的粗粒度过程
  • eureka.instance.prefer-ip-address = true 时,发生的一些事
  • 深度理解eureka.instance.ip-address 和eureka.instance.prefer-ip-address = true 。
  • 杂谈

注:本篇较长、烧脑,并且涉及的范围相对广,建议选择一个舒服的姿势阅读。

分析,eureka.instance.prefer-ip-address

  • 本节解释为什么配置eureka.instance.prefer-ip-address = true时,注册到Eureka Server上的是IP,以及是什么IP

老套路,定位问题从配置开始。

(1) 我们通过eureka.instance.prefer-ip-address 配置项,可以找到源码

org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean.preferIpAddress

(2) preferIpAddress被哪里调用,可以找到

org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean.getHostName(boolean)

代码如下:

@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;
}

从这里我们可以知道,为什么配置eureka.instance.prefer-ip-address = true 就可以将IP注册到Eureka Server上,而如果不配置就是机器的主机名。

我们看到以上代码有个hostInfo,这是在哪里实例化的呢?

(3) hostInfo在

org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean

的构造方法中实例化!我们来阅读该类的构造方法:

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

从中 可以看到,hostInfo是调用了

this.inetUtils.findFirstNonLoopbackHostInfo();

从中可以看到,原来hostInfo是调用了

org.springframework.cloud.commons.util.InetUtils.findFirstNonLoopbackHostInfo()

(4) 阅读

org.springframework.cloud.commons.util.InetUtils.findFirstNonLoopbackHostInfo()

可以看到以下代码:

public HostInfo findFirstNonLoopbackHostInfo() {InetAddress address = findFirstNonLoopbackAddress();if (address != null) {return convertAddress(address);}HostInfo hostInfo = new HostInfo();hostInfo.setHostname(this.properties.getDefaultHostname());hostInfo.setIpAddress(this.properties.getDefaultIpAddress());return hostInfo;
}

我们再看一下该类的

org.springframework.cloud.commons.util.InetUtils.findFirstNonLoopbackAddress()

方法:

Eureka Client在com.netflix.appinfo包下的InstanceInfo类封装了本机信息,其中就包括了IP地址。

在 Spring Cloud 环境下,Eureka Client并没有自己实现探测本机IP的逻辑,而是交给Spring的InetUtils工具类的findFirstNonLoopbackAddress()方法完成的具体如下:

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// 是否是被忽略的网卡if (!ignoreInterface(ifc.getDisplayName())) {for (Enumeration<InetAddress> addrs = ifc.getInetAddresses(); addrs.hasMoreElements();) {InetAddress address = addrs.nextElement();if (address instanceof Inet4Address&& !address.isLoopbackAddress()&& !ignoreAddress(address)) {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 {// 如果以上逻辑都没有找到合适的网卡,则使用JDK的InetAddress.getLocalhost()return InetAddress.getLocalHost(); }catch (UnknownHostException e) {log.warn("Unable to retrieve localhost");}return null;
}

通过源码可以看出,该工具类会获取所有网卡,依次进行遍历,取ip地址合理、索引值最小且不在忽略列表的网卡的ip地址作为结果。如果仍然没有找到合适的IP, 那么就将InetAddress.getLocalHost()做为最后的fallback方案。

至此,终于找到了获得IP的详细方法,原来只需要配置eureka.instance.prefer-ip-address = true,Spring就会自动为我们获取第一个非回环IP地址(这只是简单的说法,事实上这段代码有些容错的处理)。代码虽然长,但是很清晰。不做赘述。

eureka.instance.ip-address和eureka.instance.prefer-ip-address = true同时设置,会用自动获取的ip还是手动设置的?

上文是讨论设置eureka.instance.prefer-ip-address = true ,但没有指定eureka.instance.ip-address的情况。

那么如果两者都被指定了,Spring会怎么处理呢?

是使用eureka.instance.ip-address手动设置的IP,还是用上面自动获取的IP呢?

答案是听eureka.instance.ip-address的。

原因是:在

org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean.setIpAddress(String)

中:

public void setIpAddress(String ipAddress) {this.ipAddress = ipAddress;this.hostInfo.override = true;
}

这边设置了this.hostInfo.override,因此会导致getHostName方法不会进if语句,直接返回this.ipAddress。

@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;
}

B.T.W

回到上文的

org.springframework.cloud.commons.util.InetUtils.findFirstNonLoopbackAddress()

方法,上面有很多ignoreXXX的代码。那么,如何配置想要忽略的网卡或者IP地址呢?

答案非常简单,详见Spring Cloud官方文档:

http://cloud.spring.io/spring-cloud-static/Camden.SR3/#ignore-network-interfaces

当然了,这些配置的本意并不是用来注册到Eureka上的,而是用作其他用途,只不过如果没有设置eureka.instance.ip-address时,这个IP就是注册到Eureka Server上的IP。

我们可以在应用的/env端点看到Spring为我们挑选的IP:

springCloudClientHostInfo: {spring.cloud.client.hostname: "itmuch",spring.cloud.client.ipAddress: "192.168.0.59"
},

Eureka之IpAddress:eureka.instance.prefer-ip-address = true相关推荐

  1. AWS EC2 instance IP网络 - Private/Public/Elastic IP address

    1. 登录到EC2 instance(也即EC2虚拟机)的操作系统里边,运行查看主机网卡的命令,比如'ifconfig' or 'ip address', 默认我们能看到有一个网卡,eth0,其地址就 ...

  2. Eureka简介与Eureka Server上

    Ereka,它是一个服务发现组件,我们为什么要学习Eureka,在SpringCloud里面,他提供了多种服务发现的支持,我们可以使用ZK,我们可以使用Consul服务发现,为什么我们只讲Eureka ...

  3. SpringCloud之Eureka原理和eureka优雅停服和安全认证

    文章目录 1 Eureka 1.1 什么是Eureka注册中心 1.2 Eureka注册中心三种角色 1.2.1 Eureka Server 1.2.2 Application Service (Se ...

  4. Windows azure国际版下通过 windows auzre powershell为VM分配绑定virtual ip address

    说到windows azure,相信大家已经对此产品已经相当熟悉了,但使用的版本最多的应该是windows azure国内版本,也就是说,是微软委派世纪互联提供服务的平台,登陆地址为:https:// ...

  5. 什么是Eureka? 单机版Eureka如何使用?

    Eureka 是什么? Eureka 是Spring Cloud的服务治理组件,有三个核心角色: 服务注册中心.服务提供者.服务消费者.Eureka 主管服务注册中心. 是Netflix的一个子模块, ...

  6. Your IP address is spelled incorrectly问题排查

    nacos集成spring cloud stream时启动失败,报以下错误: Caused by: com.alibaba.nacos.api.exception.NacosException: fa ...

  7. The ip address is being used by a static-MAC user

    解决华为路由器在vlan中静态地址绑定出现"The ip address is being used by a static-MAC user"的问题 故障原因:该mac地址已经通 ...

  8. Oracle 12.2 RAC修改public ip address或public ip(subnet (netmask) or interface)方法

    Oracle 12.2 RAC修改public ip address或public ip(subnet (netmask) or interface)方法 场景:Oracle 12.2 RAC修改IP ...

  9. 1108. Defanging an IP Address

    1108. Defanging an IP Address 题目描述 Example 1: Input: address = "1.1.1.1" Output: "1[. ...

最新文章

  1. Android实训日志:基于外部存储的音乐播放器V05
  2. 我以前用过的一个洗牌算法
  3. jQuery的Autocomplete插件
  4. 【深度学习】聊聊Batch Normalization在网络结构中的位置
  5. 在本地库不连接远远程库的情况下操作远程库-----sql server
  6. 科普向,什么是 Lua 语言?
  7. Get全栈技能点 Vue2.0 / Node.js / MongoDB 打造商城系统
  8. 高手追小萝莉的故事(洛谷P1184题题解,Java语言描述)
  9. Python助力中学数学教学:绘图验证反比例函数与矩形交点的关系
  10. 百度全面开放搜索流量,进击的智能小程序!
  11. [Markdown]纯文本标记语言MarkdowPad2--MD语法知识
  12. python实现梳排序
  13. visual studio 2013 编译 filezilla和filezilla server
  14. android手机蓝牙连接扫码枪,android 扫码枪解惑
  15. 王献之碧玉小楷《洛神赋十三行》王献之小楷高清原石拓本对比图
  16. 机器学习系列15:学习曲线
  17. Windows2003 3389端口修改
  18. P1551 亲戚 (并查集)
  19. 异地远程连接在家里的群晖NAS【无公网IP,免费内网穿透】
  20. 数字图像处理(DIP)实验4 目标颜色识别

热门文章

  1. Vue 3D轮播插件vue-carousel-3d
  2. 计算机考研英语复试自我介绍范文,考研英语复试自我介绍范文10篇
  3. 己酸戊酯的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  4. 数字信号处理_第1个编程实例
  5. 阿里云 mysql emoji_如何在 MySQL 中存储 emoji ?
  6. JavaScript入门 正则表达式/元素运动 Day16
  7. 机器学习-人工智能大数据,公开的海量数据集下载
  8. java和c++复试面试题
  9. BAT 批处理脚本 教程
  10. 【Java经典小游戏】大鱼吃小鱼 (两万字保姆级教程)