好久没有更新文章了,将前几天线上的一个bug简单记录下来。技术人员需要敬畏技术,细节决定于成败。

背景

因为系统进行技术组件迁移,需要占用spring.application.name 这个配置名称。而原系统所使用技术栈为spring cloud,注册中心为eureka,业务系统所提供的服务名称在注册中心的名字所使注册的名字即为spring.application.name所配置的内容,下游业务所使用的feignclient通过服务名进行调用服务要么一起该,要么服务端要做到平滑升级。作为技术人员,当然是选择平滑升级了。

如何做到平滑升级呢?

有人说直觉很重要,也很准,但是就是这个直觉把我害惨了。为了保证系统的平滑升级,也为了缩小本次改造的影响面,所以我就选择了一个不常用服务进行了改造。
因为只需要将服务注册在euraka中注册上去名字不变即可,增加了eureka.instance.appname 参数。服务注册之后,在eureka页面看到的服务注册信息应当如下所示:

applicationstutus修改前后
spring.application.namehost_name:spring.application.name:port修改前
eureka.instance.appnamehost_name:spring.application.name:port修改后

比如我有一个hello-service服务,现在新增eureka.instance.appname,并修改原始的spring.application.name=hello-server,那么现在eureka上看到的注册服务信息为:

applicationstutus修改前后
HELLO-SERVICEhost_name:hello-service:8080修改前
HELLO-SERVICEhost_name:hello-server:8080修改后

下游服务通过feign client+服务名调用,即通过hello-service查找到相应用服务,完成调用即可。

没有进行严格测试,就上线了。

bug出现了

下游服务无法找到相应的服务提供者,即下游用户找不到服务。也就是说这个服务注册是不对的。这个看似完美的配置实则不起作用。一时没有办法,只好进行了即时回滚,完成了一波骚操作。

复盘

之所以出现这个bug,主要原因是对于eureka注册中心的数据结构不熟悉,另外对于feignclient 进行服务查找所使用的数据结构不熟悉。
另外惯性思维认为eureka上application上显示的那一列即为数据key,所以才有这个bug的出现。通过查找eureka client 源代码,只需再增加

eureka.instance.virtualHostName=hello-service
eureka.instance.secureVirtualHostName=hello-service

即可,其实服务的查找是以vipAddress 作为key进行查找,而对应的application 在eureka的内存数据结构为:

<application>
	<name>HELLO-SERVICE</name>
	<instance>
		<instanceId>192.168.0.107:hello-server:8082</instanceId>
		<hostName>192.168.0.107</hostName>
		<app>HELLO-SERVICE</app>
		<ipAddr>192.168.0.107</ipAddr>
		<status>UP</status>
		<overriddenstatus>UNKNOWN</overriddenstatus>
		<port enabled="true">8082</port>
		<securePort enabled="false">443</securePort>
		<countryId>1</countryId>
		<dataCenterInfo class="com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo">
		<name>MyOwn</name>
		</dataCenterInfo>
		<leaseInfo>
		<renewalIntervalInSecs>30</renewalIntervalInSecs>
		<durationInSecs>90</durationInSecs>
		<registrationTimestamp>1602386555846</registrationTimestamp>
		<lastRenewalTimestamp>1602386555846</lastRenewalTimestamp>
		<evictionTimestamp>0</evictionTimestamp>
		<serviceUpTimestamp>1602386555846</serviceUpTimestamp>
		</leaseInfo>
		<metadata class="java.util.Collections$EmptyMap"/>
		<homePageUrl>http://192.168.0.107:8082/</homePageUrl>
		<statusPageUrl>http://192.168.0.107:8082/info</statusPageUrl>
		<healthCheckUrl>http://192.168.0.107:8082/health</healthCheckUrl>
		<vipAddress>hello-server</vipAddress>
		<secureVipAddress>hello-server</secureVipAddress>
		<isCoordinatingDiscoveryServer>false</isCoordinatingDiscoveryServer>
		<lastUpdatedTimestamp>1602386555846</lastUpdatedTimestamp>
		<lastDirtyTimestamp>1602386555797</lastDirtyTimestamp>
		<actionType>ADDED</actionType>
	</instance>
</application>
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐