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

简介: 阅读本文你将了解微服务注册到Eureka Server上的粗粒度过程为什么appname是大写。appName的配置:spring.application.name与eureka.instance.appname,及它们的优先级。

阅读本文你将了解

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

Prepare

首先解释一下什么是appname

10-2.png

图中的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

本文链接: http://www.itmuch.com/spring-cloud-code-read/spring-cloud-code-read-eureka-registry-appname/
**版权声明: **本博客由周立创作,采用 CC BY 3.0 CN 许可协议。可自由转载、引用,但需署名作者且注明文章出处。如转载至微信公众号,请在文末添加作者公众号二维码。

目录
相关文章
|
Java 网络安全 Nacos
Nacos作为流行的微服务注册与配置中心,其稳定性与易用性广受好评
Nacos作为流行的微服务注册与配置中心,其稳定性与易用性广受好评。然而,“客户端不发送心跳检测”是使用中常见的问题之一。本文详细探讨了该问题的原因及解决方法,包括检查客户端配置、网络连接、日志、版本兼容性、心跳检测策略、服务实例注册状态、重启应用及环境变量等步骤,旨在帮助开发者快速定位并解决问题,确保服务正常运行。
224 5
|
网络安全 Nacos 开发者
Nacos作为流行的微服务注册与配置中心,“节点提示暂时不可用”是常见的问题之一
Nacos作为流行的微服务注册与配置中心,其稳定性和易用性备受青睐。然而,“节点提示暂时不可用”是常见的问题之一。本文将探讨该问题的原因及解决方案,帮助开发者快速定位并解决问题,确保服务的正常运行。通过检查服务实例状态、网络连接、Nacos配置、调整健康检查策略等步骤,可以有效解决这一问题。
281 4
|
Java 网络安全 Nacos
Nacos作为流行的微服务注册与配置中心,其稳定性和易用性备受青睐。
Nacos作为流行的微服务注册与配置中心,其稳定性和易用性备受青睐。然而,实际使用中常遇到“客户端不发送心跳检测”的问题。本文深入探讨该问题的原因及解决方案,帮助开发者快速定位并解决问题,确保服务正常运行。通过检查客户端配置、网络连接、日志、版本兼容性、心跳策略、注册状态、重启应用和环境变量等步骤,系统地排查和解决这一问题。
242 3
|
安全 Nacos 数据库
Nacos是一款流行的微服务注册与配置中心,但直接暴露在公网中可能导致非法访问和数据库篡改
Nacos是一款流行的微服务注册与配置中心,但直接暴露在公网中可能导致非法访问和数据库篡改。本文详细探讨了这一问题的原因及解决方案,包括限制公网访问、使用HTTPS、强化数据库安全、启用访问控制、监控和审计等步骤,帮助开发者确保服务的安全运行。
668 3
|
负载均衡 算法 Nacos
SpringCloud 微服务nacos和eureka
SpringCloud 微服务nacos和eureka
262 0
|
负载均衡 Java Nacos
EureKa详解:微服务发现与注册的利器
EureKa详解:微服务发现与注册的利器
|
Kubernetes Nacos 微服务
微服务注册与发现的原理与实现
微服务注册与发现的原理与实现
|
存储 缓存 Java
Eureka原理与实践:深入探索微服务架构的核心组件
在微服务架构日益盛行的今天,服务之间的注册与发现成为了保证系统高可用性和灵活性的关键。Eureka,作为Netflix开源的服务注册与发现框架,凭借其简单、健壮的特性,在微服务领域占据了举足轻重的地位。本文将深入剖析Eureka的原理,并通过实践案例展示其在实际项目中的应用,以期为开发者提供一个高端、深入的视角。
256 0
|
Kubernetes Nacos 微服务
【技术难题破解】Nacos v2.2.3 + K8s 微服务注册:强制删除 Pod 却不消失?!7步排查法+实战代码,手把手教你解决Nacos Pod僵死问题,让服务瞬间满血复活!
【8月更文挑战第15天】Nacos作为微服务注册与配置中心受到欢迎,但有时会遇到“v2.2.3 k8s 微服务注册nacos强制删除 pod不消失”的问题。本文介绍此现象及其解决方法,帮助开发者确保服务稳定运行。首先需检查Pod状态与事件、配置文件及Nacos配置,确认无误后可调整Pod生命周期管理,并检查Kubernetes版本兼容性。若问题持续,考虑使用Finalizers、审查Nacos日志或借助Kubernetes诊断工具。必要时,可尝试手动强制删除Pod。通过系统排查,通常能有效解决此问题。
479 0
|
设计模式 Java API
微服务架构演变与架构设计深度解析
【11月更文挑战第14天】在当今的IT行业中,微服务架构已经成为构建大型、复杂系统的重要范式。本文将从微服务架构的背景、业务场景、功能点、底层原理、实战、设计模式等多个方面进行深度解析,并结合京东电商的案例,探讨微服务架构在实际应用中的实施与效果。
690 6

热门文章

最新文章