在SpringCloud组件:Eureka服务注册是采用主机名还是IP地址?文章中我们讲到了服务注册的几种注册方式,那么这几种注册方式的源码是怎么实现的呢?我们带着这一个疑问来阅读本章内容能够让你更深入了解这块的知识点!!!

本章目标

分析每一种服务注册方式源码执行流程。

构建项目

本章以分析源码为主,所以不去新创建项目来讲解相关内容,我们使用SpringCloud组件:Eureka服务注册是采用主机名还是IP地址?源码作为注册服务,SpringCloud组件:搭建Eureka服务注册中心源码作为服务注册中心,还是按照之前的运行流程:

  1. 启动服务注册中心
  2. 启动本章服务项目
  3. 查看服务列表,服务注册方式

配置信息获取执行流程

在开始讲解本章注册方式之前,我们需要了解整体的配置信息获取的流程信息,这样才可以分析指定的注册方式执行流程。

第一步:实例化EurekaInstanceConfigBean配置实体

在项目启动时由于依赖spring-cloud-starter-netflix-eureka-client内通过配置spring.factories文件来让项目启动时自动加载并实例化org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration配置类,EurekaClientAutoConfiguration内会自动实例化EurekaInstanceConfigBean并且自动绑定eureka.instance开头的配置信息(具体为什么会自动映射可以去了解下@ConfigurationProperties注解作用),部分源码如下所示:

......
public class EurekaClientAutoConfiguration {//省略部分源码@Bean@ConditionalOnMissingBean(value = EurekaInstanceConfig.class, search        = SearchStrategy.CURRENT)public EurekaInstanceConfigBean eurekaInstanceConfigBean(InetUtils inetUtils,                                                     ManagementMetadataProvider managementMetadataProvider) {//省略部分源码// 传递EurekaInstanceConfigBean instance = new EurekaInstanceConfigBean(inetUtils);// 省略部分源码}//省略部分源码
}
复制代码

EurekaClientAutoConfiguration#eurekaInstanceConfigBean方法只有满足@ConditionalOnMissingBean(value = EurekaInstanceConfig.class, search = SearchStrategy.CURRENT)表达式后才会去实例化,并且把实例化对象放入到IOC容器内容,BeanIdeurekaInstanceConfigBean,也就是方法的名称。 在EurekaClientAutoConfiguration#eurekaInstanceConfigBean方法中有这么一行代码我们可以进行下一步的分析

// 通过有参构造函数实例化EurekaInstanceConfigBean配置实体
EurekaInstanceConfigBean instance = new EurekaInstanceConfigBean(inetUtils);
复制代码

通过调用EurekaInstanceConfigBean(InetUtils inetUtils)构造函数来进行实例化EurekaInstanceConfigBean对象,在这个构造函数内也有一些实例化的工作,源码如下:

public EurekaInstanceConfigBean(InetUtils inetUtils) {this.inetUtils = inetUtils;this.hostInfo = this.inetUtils.findFirstNonLoopbackHostInfo();this.ipAddress = this.hostInfo.getIpAddress();this.hostname = this.hostInfo.getHostname();
}
复制代码
第二步:InetUtils#findFirstNonLoopbackHostInfo获取主机基本信息

在构造函数EurekaInstanceConfigBean(InetUtils inetUtils)源码实现内hostInfo主机信息通过了InetUtils#findFirstNonLoopbackHostInfo方法来进行实例化,我们来看看这个方法的具体实现逻辑,它会自动读取系统网卡列表然再进行循环遍历查询正在UP状态的网卡信息,如果没有查询到网卡信息,则使用默认的HostNameIpAddress配置信息,源码如下所示:

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;
}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:offif (!ignoreInterface(ifc.getDisplayName())) {for (Enumeration<InetAddress> 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}}}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;
}
复制代码

默认的HostNameIpAddress属性配置信息在InetUtilsProperties配置实体类内,如果不进行设置则直接使用默认值,如果你想更换默认值,那么你可以在application.yml配置文件内通过设置spring.cloud.inetutils.defaultHostnamespring.cloud.inetutils.defaultIpAddress进行修改默认值,源码如下所示:

public class InetUtilsProperties {public static final String PREFIX = "spring.cloud.inetutils";/*** The default hostname. Used in case of errors.*/private String defaultHostname = "localhost";/*** The default ipaddress. Used in case of errors.*/private String defaultIpAddress = "127.0.0.1";
}
复制代码
第三步:EurekaInstanceConfigBean#getHostName方法实现

getHostName是一个Override的方法,继承于com.netflix.appinfo.EurekaInstanceConfig接口,该方法有个boolean类型的参数refresh来判断是否需要刷新重新获取主机网络基本信息,当传递refresh=false并且在application.yml配置文件内并没有进行手动设置eureka.instance.hostname以及eureka.instance.ip-address参数则会根据eureka.instance.prefer-ip-address设置的值进行返回信息,源码如下所示:

@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;
}
复制代码

默认注册方式源码分析

由于在实例化EurekaInstanceConfigBean配置实体类时,构造函数进行了获取第一个非回环主机信息,默认的hostName以及ipAddress参数则是会直接使用InetUtils#findFirstNonLoopbackHostInfo方法返回的相对应的值。

IP优先注册方式源码分析

EurekaInstanceConfigBean#getHostName方法直接调用本类重载方法getHostName(boolean refresh)并且传递参数为false,根据第三步源码我们就可以看到:

return this.preferIpAddress ? this.ipAddress : this.hostname;
复制代码

如果eureka.instance.prefer-ip-address参数设置了true就会返回eureka.instance.ip-address的值,这样我们就可以从中明白为什么主动设置eureka.instance.ip-address参数后需要同时设置eureka.instance.prefer-ip-address参数才可以生效。

指定IP、HostName源码分析

我们通过application.yml配置文件进行设置eureka.instance.hostname以及eureka.instance.ip-address后会直接替换原默认值,在EurekaInstanceConfigBean#getHostName中也是返回的this.hostnamethis.ipAddress所以在这里设置后会直接生效作为返回的配置值。

总结

我们通过源码进行分析服务注册方式执行流程,这样在以后进行配置eureka.instance.hostnameeureka.instance.prefer.ip-addresseureka.instance.ip-address三个配置信息时就可以根据优先级顺序达到预期的效果,避免没有必要的错误出现。

源码位置

  • SpringBoot配套源码地址:访问码云查看源码、访问GitHub查看源码
  • SpringCloud配套源码地址(本章源码在这):访问码云查看源码

有问题要问?

如果你有技术相关的问题想要咨询恒宇少年,请去博客首页左侧导航栏,点击知识星球微信扫码加入我的星球。

与恒宇少年面对面

如果你喜欢恒宇少年的相关文章,那么就去微信公众号(恒宇少年)关注我吧!!! 当然你也可以去 SpringCloud码云源码 项目底部扫描微信公众号二维码关注我,感谢阅读!!!

学习目录推荐

  • SpringCloud相关系列文章访问:www.jianshu.com/p/64e4aaada…
  • SpringBoot相关系列文章请访问:www.jianshu.com/p/9a08417e4…
  • QueryDSL相关系列文章请访问:www.jianshu.com/p/99a5ec5c3…
  • SpringDataJPA相关系列文章请访问:www.jianshu.com/p/615ed9c1f…

开源信息

这段时间一直在编写开源的相关框架,致力于公司使用的框架升级以及开源计划,将公司使用到的工具以及插件进行升级重构并且开源。

  • 代码生成器(Code-Builder) code-builder代码生成器根据你提供的模板文件(目前支持freemarker)自动生成实体类,可以很大很有效的提高开发效率。 Gitee地址:gitee.com/hengboy/cod… Github地址:github.com/hengyuboy/c…
  • 持久化框架(MyBatis-Enhance) mybatis-enhance是一个对mybatis框架的增强封装,提供一系列的内部方法来完成单表数据的操作,多表数据提供DSL方式进行操作。 Gitee地址:gitee.com/hengboy/myb… Github地址:github.com/hengyuboy/m…
  • 自动分页插件 MyBatis-Pageable是一款自动化分页的插件,基于MyBatis内部的插件Interceptor拦截器编写完成,拦截Executor.query的两个重载方法计算出分页的信息以及根据配置的数据库Dialect自动执行不同的查询语句完成总数量的统计。 Gitee地址:gitee.com/hengboy/myb…

SpringCloud组件 源码剖析:Eureka服务注册方式流程全面分析相关推荐

  1. Netty 源码解析系列-服务端启动流程解析

    netty源码解析系列 Netty 源码解析系列-服务端启动流程解析 Netty 源码解析系列-客户端连接接入及读I/O解析 五分钟就能看懂pipeline模型 -Netty 源码解析 1.服务端启动 ...

  2. 跟着狂神学SpringCloud(Rest环境搭建+Eureka服务注册与发现+ribbon+Feign负载均衡+Hystrix+服务熔断+Zuul路由网关+SpringCloud config分布)

    跟着狂神学SpringCloud SpringCloud 回顾之前的知识- JavaSE 数据库 前端 Servlet Http Mybatis Spring SpringMVC SpringBoot ...

  3. 源码剖析 Netty 服务启动 NIO

    如果这个文章看不懂的话 , 建议反复阅读 Netty 与 Reactor 开篇立意.引用网友好的建议.看源码要针对性的看,最佳实践就是,带着明确的目的去看源码.抓主要问题,放弃小问题.主要的逻辑理解了 ...

  4. SpringCloud笔记(Hoxton)——Netflix之Eureka服务注册与发现

    基础应用 Eureka简介 Eureka是一个基于REST的服务,主要在AWS云中使用,定位服务来进行中间层服务器的负载均衡和故障转移. SpringCloud封装了Netflix公司开发的Eurek ...

  5. python源码剖析 豆瓣_在数据分析师的分析中豆瓣的书那些值得读

    最近总是有人问我有什么书好推荐看看,特烦.但是看到那么多人问,看来挺多人有这个需求,便想了一下,如何通过数据分析找到值得看的书.通过爬取某个标签例如产品,运营获取对应已经打了标签的书,获取书对应的评分 ...

  6. Nacos源码系列—关于服务注册的那些事

    点赞再看,养成习惯,微信搜索[牧小农]关注我获取更多资讯,风里雨里,小农等你,很高兴能够成为你的朋友. 项目源码地址:公众号回复 nacos,即可免费获取源码 简介 首先我们在看Nacos源码之前,要 ...

  7. eureka源码:开启服务注册

  8. redis源码剖析(十三)—— dump.rdb文件分析

    文章目录 操作方式 查看rdb文件 参考文档 redis作者解释rdb和aof的不同 redisRDB文件格式Sripathi Krishnam redis各个版本变化 操作方式 127.0.0.1: ...

  9. Nacos服务注册与发现源码剖析

    文章目录 前提介绍 Nacos源码下载 Nacos客户端源码 Spring Cloud Starter Nacos 源码 Nacos服务端源码 前提介绍 服务注册与发现作用主要是为了更好的管理众多的服 ...

最新文章

  1. Linux创建线程时 内存分配的那些事
  2. Android系统架构-[Android取经之路]
  3. linux裁剪—定制自己所需要的linux
  4. 借助Docker单机秒开数十万TCP连接
  5. MySQL之父直播公开课来了!与腾讯云CDB专家天团联袂分享
  6. 前端学习(2250)拉取代码文件
  7. C++ functor 仿函数
  8. 详述一则DB2 Error Code 1639和SQL State 08001案例诊断和解决方案
  9. 中国联通自主5G手机品牌U-MAGIC首款旗舰产品将于3月28日发布
  10. 客快物流大数据项目(二):物流项目详细介绍
  11. 世界500强榜单出炉:中国公司首进三强 沃尔玛居首
  12. 一个故事贯穿设计模式小例子练习源码
  13. java 通配符 删除文件_jQuery removeClass通配符
  14. NSG2 安装、运行备忘
  15. 如何让计算机停止打印,电脑打印提示print Splooer停止无法使用怎么办
  16. js技术输入框中输入身份证号自动带出年龄,生日,性别
  17. Tableau权限设置
  18. 安装 office 2016
  19. 中南大学计算机专业男女比例,中南大学相亲网上线 目前男女比例过于悬殊
  20. 判断linux标准输入法,[fcitx]linux下的中文输入法(非准确)

热门文章

  1. MySQL第11天:MySQL索引优化分析之性能分析
  2. 设计模式:单例模式之饿汉式
  3. jvm四:常量的本质含义以及助记符基本认识
  4. C#中[WebMethod]的用法,aspx、ashx、asmx
  5. 【毕设进行时-工业大数据,数据挖掘】Java GUI完善,左对齐
  6. textarea标签中的换行与空格问题
  7. Struts2 整合jQuery实现Ajax功能(2)
  8. 浏览器显示XML文档
  9. openfire + spark + sparkweb + pandion 下载地址
  10. C语言 矩阵的几种乘法