spring.application.name改名引发的bug

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

背景

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

如何做到平滑升级呢?

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

application stutus 修改前后
spring.application.name host_name:spring.application.name:port 修改前
eureka.instance.appname host_name:spring.application.name:port 修改后

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

application stutus 修改前后
HELLO-SERVICE host_name:hello-service:8080 修改前
HELLO-SERVICE host_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-SERVICEname>
	<instance>
		<instanceId>192.168.0.107:hello-server:8082instanceId>
		<hostName>192.168.0.107hostName>
		<app>HELLO-SERVICEapp>
		<ipAddr>192.168.0.107ipAddr>
		<status>UPstatus>
		<overriddenstatus>UNKNOWNoverriddenstatus>
		<port enabled="true">8082port>
		<securePort enabled="false">443securePort>
		<countryId>1countryId>
		<dataCenterInfo class="com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo">
		<name>MyOwnname>
		dataCenterInfo>
		<leaseInfo>
		<renewalIntervalInSecs>30renewalIntervalInSecs>
		<durationInSecs>90durationInSecs>
		<registrationTimestamp>1602386555846registrationTimestamp>
		<lastRenewalTimestamp>1602386555846lastRenewalTimestamp>
		<evictionTimestamp>0evictionTimestamp>
		<serviceUpTimestamp>1602386555846serviceUpTimestamp>
		leaseInfo>
		<metadata class="java.util.Collections$EmptyMap"/>
		<homePageUrl>http://192.168.0.107:8082/homePageUrl>
		<statusPageUrl>http://192.168.0.107:8082/infostatusPageUrl>
		<healthCheckUrl>http://192.168.0.107:8082/healthhealthCheckUrl>
		<vipAddress>hello-servervipAddress>
		<secureVipAddress>hello-serversecureVipAddress>
		<isCoordinatingDiscoveryServer>falseisCoordinatingDiscoveryServer>
		<lastUpdatedTimestamp>1602386555846lastUpdatedTimestamp>
		<lastDirtyTimestamp>1602386555797lastDirtyTimestamp>
		<actionType>ADDEDactionType>
	instance>
application>

你可能感兴趣的:(框架,springcloud,java,spring,spring,boot)