理解微服务注册到Eureka Server上的过程(以appname为例)

阅读本文你将了解

  • 微服务注册到Eureka Server上的粗粒度过程
  • 为什么appname是大写。
  • appName的配置:spring.application.name与eureka.instance.appname,及它们的优先级。

Prepare

首先解释一下什么是appname

图中的MICROSERVICE-PROVIDER-USER就是appname。下面我们来分析一下它的详细逻辑。

分析

(1) 首先找到:org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration.EurekaClientConfiguration.eurekaApplicationInfoManager(EurekaInstanceConfig)

里面有以下代码:

 
    
@Bean
@ConditionalOnMissingBean(value = ApplicationInfoManager. class, search = SearchStrategy.CURRENT)
public ApplicationInfoManager eurekaApplicationInfoManager(EurekaInstanceConfig config) {
InstanceInfo instanceInfo = new InstanceInfoFactory().create(config);
return new ApplicationInfoManager(config, instanceInfo);
}

从中,可以看到,该方法调用了new InstanceInfoFactory().create(config); 。

(2) 跟进org.springframework.cloud.netflix.eureka.InstanceInfoFactory.create(EurekaInstanceConfig) ,可以看到以下代码:

 
    
public InstanceInfo create(EurekaInstanceConfig config) {
LeaseInfo .Builder leaseInfoBuilder = LeaseInfo .Builder .newBuilder()
.setRenewalIntervalInSecs( config .getLeaseRenewalIntervalInSeconds())
.setDurationInSecs( config .getLeaseExpirationDurationInSeconds());
// Builder the instance information to be registered with eureka
// server
InstanceInfo.Builder builder = InstanceInfo.Builder.newBuilder();
String namespace = config.getNamespace();
if (! namespace.endsWith( ".")) {
namespace = namespace + ".";
}
builder .setNamespace( namespace) .setAppName( config .getAppname())
.setInstanceId( config .getInstanceId())
.setAppGroupName( config .getAppGroupName())
.setDataCenterInfo( config .getDataCenterInfo())
.setIPAddr( config .getIpAddress()) .setHostName( config .getHostName( false))
.setPort( config .getNonSecurePort())
.enablePort( InstanceInfo .PortType .UNSECURE,
config .isNonSecurePortEnabled())
.setSecurePort( config .getSecurePort())
.enablePort( InstanceInfo .PortType .SECURE, config .getSecurePortEnabled())
.setVIPAddress( config .getVirtualHostName())
.setSecureVIPAddress( config .getSecureVirtualHostName())
.setHomePageUrl(config.getHomePageUrlPath(), config.getHomePageUrl( ))
.setStatusPageUrl( config .getStatusPageUrlPath(),
config .getStatusPageUrl())
.setHealthCheckUrls( config .getHealthCheckUrlPath(),
config .getHealthCheckUrl(), config .getSecureHealthCheckUrl())
.setASGName( config .getASGName());
// Start off with the STARTING state to avoid traffic
if (!config.isInstanceEnabledOnit()) {
InstanceInfo.InstanceStatus initialStatus = InstanceInfo.InstanceStatus.STARTING;
if ( log.isInfoEnabled()) {
log.info( "Setting initial instance status as: " + initialStatus);
}
builder .setStatus(initialStatus);
}
else {
if ( log.isInfoEnabled()) {
log.info( "Setting initial instance status as: "
+ InstanceInfo .InstanceStatus .UP
+ ". This may be too early for the instance to advertise itself as available. "
+ "You would instead want to control this via a healthcheck handler.");
}
}
// Add any user-specific metadata information
for ( Map.Entry< String, String> mapEntry : config.getMetadataMap().entrySet()) {
String key = mapEntry.getKey();
String value = mapEntry.getValue();
builder. add(key, value);
}
InstanceInfo instanceInfo = builder.build();
instanceInfo .setLeaseInfo( leaseInfoBuilder .build());
return instanceInfo;
}

代码比较长,但是不难看出,该代码是在通过传入的配置,去构建一个InstanceInfo,也就是某个微服务实例的各种信息。

在代码中,找到以下代码:

 
    
builder .setNamespace( namespace) .setAppName( config .getAppname())
.setInstanceId( config .getInstanceId())

我们不妨跟进setAppname中看看。

(3) 查看com.netflix.appinfo.InstanceInfo.Builder.setAppName(String)

 
    
public Builder setAppName(String appName) {
result.appName = StringCache.intern(appName.toUpperCase(Locale.ROOT));
return this;
}

我们可以看到,是该方法将appName转大写了。

(4) 回到

 
    
builder .setNamespace( namespace) .setAppName( config .getAppname())
.setInstanceId( config .getInstanceId())

这段代码,通过DEBUG,我们可以看到代码中的config,是

 
    
org .springframework .cloud .netflix .eureka .EurekaInstanceConfigBean

(5) 查看该类,我们会发现这正式Eureka Instance的配置类。因此,我们可以使用eureka.instance.appname去配置appName。

 
    
@Data
@ ConfigurationProperties(" eureka. instance")
public class EurekaInstanceConfigBean implements CloudEurekaInstanceConfig, EnvironmentAware, InitializingBean {
private static final String UNKNOWN = "unknown";
@ Getter( AccessLevel. PRIVATE)
@ Setter( AccessLevel. PRIVATE)
private HostInfo hostInfo;
@ Getter( AccessLevel. PRIVATE)
@ Setter( AccessLevel. PRIVATE)
private InetUtils inetUtils;
/**
* Get the name of the application to be registered with eureka.
*/
private String appname = UNKNOWN;

(6) 那么,为什么我们可以通过spring.application.name去配置微服务的appName呢?代码在这里:

org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean.afterPropertiesSet()

 
    
@Override
public void afterPropertiesSet() throws Exception {
RelaxedPropertyResolver springPropertyResolver = new RelaxedPropertyResolver( this.environment, "spring.application.");
String springAppName = springPropertyResolver.getProperty( "name");
if(StringUtils.hasText(springAppName)) {
setAppname( springAppName) ;
setVirtualHostName( springAppName) ;
setSecureVirtualHostName( springAppName) ;
}
}

经过以上分析,我们可以看到spring.application.name的优先级比eureka.instance.appname高。例如:

 
    
server:
port: 8000
spring:
application:
name: microservice-provider-user
eureka:
client:
serviceUrl:
defaultZone: http: //localhost:8761/eureka/
instance:
appname: abc
prefer-ip- address: true

两者都配置的时候,注册到Eureka Server上的appname是microservice-provider-user

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值