阅读本文你将了解
微服务注册到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)
里面有以下代码:
1 2 3 4 5 6 @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) ,可以看到以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 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,也就是某个微服务实例的各种信息。
在代码中,找到以下代码:
1 2 builder.setNamespace(namespace).setAppName(config.getAppname()) .setInstanceId(config.getInstanceId())
我们不妨跟进setAppname中看看。
(3) 查看com.netflix.appinfo.InstanceInfo.Builder.setAppName(String)
1 2 3 4 public Builder setAppName(String appName) { result.appName = StringCache.intern(appName.toUpperCase(Locale.ROOT)); return this; }
我们可以看到,是该方法将appName转大写了。
(4) 回到
1 2 builder.setNamespace(namespace).setAppName(config.getAppname()) .setInstanceId(config.getInstanceId())
这段代码,通过DEBUG,我们可以看到代码中的config,是
1 org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean
(5) 查看该类,我们会发现这正式Eureka Instance的配置类。因此,我们可以使用eureka.instance.appname去配置appName。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @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()
1 2 3 4 5 6 7 8 9 10 @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高。例如:
1 2 3 4 5 6 7 8 9 10 11 12 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
相关文章
评论系统未开启,无法评论!