聊聊eureka的appname属性

本文主要研究一下eureka的appname属性

配置

eureka.instance.appname

    {
      "sourceType": "org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean",
      "defaultValue": "unknown",
      "name": "eureka.instance.appname",
      "description": "Get the name of the application to be registered with eureka.",
      "type": "java.lang.String"
    }

可以看到默认是unknown

EurekaInstanceConfigBean

spring-cloud-netflix-eureka-client-2.0.0.RC1-sources.jar!/org/springframework/cloud/netflix/eureka/EurekaInstanceConfigBean.java

@ConfigurationProperties("eureka.instance")
public class EurekaInstanceConfigBean implements CloudEurekaInstanceConfig, EnvironmentAware {
    //......
	/**
	 * Get the name of the application to be registered with eureka.
	 */
	private String appname = UNKNOWN;

	@Override
	public void setEnvironment(Environment environment) {
		this.environment = environment;
		// set some defaults from the environment, but allow the defaults to use relaxed binding
		String springAppName = this.environment.getProperty("spring.application.name", "");
		if(StringUtils.hasText(springAppName)) {
			setAppname(springAppName);
			setVirtualHostName(springAppName);
			setSecureVirtualHostName(springAppName);
		}
	}
//......
}

可以看到这里实现了EnvironmentAware接口的setEnvironment方法,里头根据spring.application.name属性的配置,如果有值则设置到eureka.instance.appname的属性上。

使用

创建

spring-cloud-netflix-eureka-client-2.0.0.RC1-sources.jar!/org/springframework/cloud/netflix/eureka/InstanceInfoFactory.java

public class InstanceInfoFactory {

	private static final Log log = LogFactory.getLog(InstanceInfoFactory.class);

	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();
			// only add the metadata if the value is present
			if (value != null && !value.isEmpty()) {
				builder.add(key, value);
			}
		}

		InstanceInfo instanceInfo = builder.build();
		instanceInfo.setLeaseInfo(leaseInfoBuilder.build());
		return instanceInfo;
	}
}

这里创建InstanceInfo的时候,其appName的值取的就是EurekaInstanceConfig. getAppname()

查询

spring-cloud-netflix-eureka-client-2.0.0.RC1-sources.jar!/org/springframework/cloud/netflix/eureka/serviceregistry/EurekaServiceRegistry.java

	@Override
	public Object getStatus(EurekaRegistration registration) {
		String appname = registration.getInstanceConfig().getAppname();
		String instanceId = registration.getInstanceConfig().getInstanceId();
		InstanceInfo info = registration.getEurekaClient().getInstanceInfo(appname, instanceId);

		HashMap<String, Object> status = new HashMap<>();
		if (info != null) {
			status.put("status", info.getStatus().toString());
			status.put("overriddenStatus", info.getOverriddenStatus().toString());
		} else {
			status.put("status", UNKNOWN.toString());
		}

		return status;
	}

这里getStatus的时候,getEurekaClient().getInstanceInfo传入appname

小结

spring cloud eureka优先使用spring.application.name值来覆盖eureka.instance.appname的值,而eureka.instance.appname默认为unknown。如果你发现你的服务在eureka的appName是unknown,则需要看下是否有设置spring.application.name。

doc

猜你喜欢

转载自my.oschina.net/go4it/blog/1815424
今日推荐