1、docker部署时,注册到Eureka server的instanceId获取到容器的hostname或者IP不正确
原因:在docker容器中,会有多个网卡,见下图:
spring-cloud-common包里的InetUtils.findFirstNonLoopbackHostInfo()方法定义了Eureka Client在注册时,会使用服务器的第一个非环回地址进行注册。
通过查看docker容器的网络情况,可以了解到在整个Spring Cloud部署的过程中,使用的网络是10.0.0.*网段的地址,其他的地址在各服务间是不通的。
通过读代码,发现有两个方法ignoreInterfaces和ignoreAddresses,可以根据在配置文件里配置spring.cloud.inetutils.ignoredInterfaces去忽略其他干扰网卡。
解决办法:在application.properties里增加忽略网卡配置:
spring.cloud.inetutils.ignoredInterfaces[0]=lo
spring.cloud.inetutils.ignoredInterfaces[1]=eth0
spring.cloud.inetutils.ignoredInterfaces[2]=eth1
2、在使用Swarm编排时,即使配置了忽略网卡,注册到Eureka上的instanceId仍然不正确,并且每次重新编排时,注册的网卡都不一样
原因:在工程启动时,Spring会加载spring-cloud-netflix-eureka-client包里的EurekaInstanceConfigBean,其中这句就是设置注册到Eureka的默认instanceId。
但是,spring.cloud.client.hostname是从ingress网络获取的,而此时overlay网络还没有准备好,这个时候看到的现象就是HostInfoEnvironmentPostProcessor已经将hostname和IP设置到系统缺省值里:
此时通过getFirstNonLoopbackHostInfo方法获取的hostname和IPAddress并不是读取了spring.cloud.inetutils.ignoredInterfaces配置项过滤之后的hostname和IPAddress。
而docker容器启动时网卡的顺序可能不一样,因此注册到Eureka上看到的instanceId每次都可能是不同网卡上的。
解决办法:重写EurekaInstanceConfigBean,设置正确的instanceId。