SpringCloud Eureka 源码分析

Eureka架构分析 以及 SpringCloud集成Eureka源码分析
摘要由CSDN通过智能技术生成

目录

SpringCloud-Eureka

整合项目

https://github.com/spring-cloud/spring-cloud-netflix

spring-cloud-netflix-eureka-server

spring-cloud-netflix-eureka-client

SpringCloud 集成Netflix的组件说明文档地址

Netflix的Wikihttps://github.com/Netflix/eureka/wiki

Eureka架构图

image

关键概念
Region(区域)
  • 属于AWS概念,主要为了给基础设施服务划分区域,实现高可用,提高网络传输速度。
Zone(可用区)
  • 属于AWS概念,为了实现高可用,在每个Region中可以有多个Zone,且每个Zone都是独立的,一个可用区出问题不会影响到其他可用区,这样也可以实现网络的低延迟。上图中的us-east-1c表示的就是一个可用区。
租约(lease)
  • Eureka Server 用于管理Erueka Client(主要管理Application Service)
  • 客户端通过每隔30秒,向Eureka Server发送心跳来续约,如果Eureka Server在90秒内没有收到客户端的续约,则会将该客户端从注册表里删除。
Eureka Server
  • 提供服务的注册和发现的功能
  • Register 提供服务注册功能
  • Renew 提供服务续租约(lease)功能
  • Cancel 提供服务注销功能
  • Get Registry 提供注册表获取功能,即服务发现
Application Service
  • 服务提供者。
Application Client
  • 服务消费者,每个client会缓存注册表的信息,这样可以再Eureka Server不可用的时候,不影响服务消费者同服务提供者的交互,同ZK的主要区别,即实现CAP中的AP。

SpringCloud启动Eureka 的过程:

EnableEurekaServer注解

SpringCloud通过注解EnableEurekaServer启动eureka服务,其包含了EnableDiscoveryClient。

SpringCloud与jersey Rest框架

eureka 基于jersey实现Rest服务,因此,如果不想采用jersey,则只需要过滤相关包的依赖即可,SpringCLoud则会采用RestTemplate来发送Rest请求。这也说明了eureka其是基于Servlet实现的。

jersey启动

SpringCloud在容器启动的时候,动态添加过滤器servletContainer 并拦截/eureka/* 的url。在该过滤器初始化的时候便加载了com.sun.jersey.spi.container.servlet.ServletContainer 该filter包含的classes有:作为jersey的WebComponentResourceConfig
- com.netflix.eureka.resources.ASGResource
- com.netflix.discovery.provider.DiscoveryJerseyProvider
- com.netflix.eureka.resources.ApplicationsResource
- com.netflix.eureka.resources.StatusResource
- com.netflix.eureka.resources.PeerReplicationResource
- com.netflix.eureka.resources.VIPResource
- com.netflix.eureka.resources.ServerInfoResource
- com.netflix.eureka.resources.InstancesResource
- com.netflix.eureka.resources.SecureVIPResource

再通过WebApplicationProvider初始化jersey服务。具体实现为WebApplicationImpl._initiate方法。

WebApplicationFactory

public static WebApplication createWebApplication() throws ContainerException {
    for (WebApplicationProvider wap : ServiceFinder.find(WebApplicationProvider.class)) {
        // Use the first provider found
        // 创建jersey服务
        return wap.createWebApplication();
    }
    throw new ContainerException("No WebApplication provider is present");
}

再由com.sun.jersey.core.spi.component.ProviderFactory 通过反射实例化com.netflix.discovery.provider.DiscoveryJerseyProvider负责将对象实例化和反序列化发送到eureka服务器

    private ComponentProvider __getComponentProvider(Class c) {
        try {
            ComponentInjector ci = new ComponentInjector(this.ipc, c);
            ComponentConstructor cc = new ComponentConstructor(this.ipc, c, ci);
            // 实例化Provider
            Object o = cc.getInstance();
            return new ProviderFactory.SingletonComponentProvider(ci, o);
        } catch (NoClassDefFoundError var5) {
            LOGGER.log(Level.CONFIG, "A dependent class, " + var5.getLocalizedMessage() + ", of the component " + c + " is not found." + " The component is ignored.");
            return null;
        } catch (InvocationTargetException var6) {
            if(var6.getCause() instanceof NoClassDefFoundError) {
                NoClassDefFoundError ncdf = (NoClassDefFoundError)var6.getCause();
                LOGGER.log(Level.CONFIG, "A dependent class, " + ncdf.getLocalizedMessage() + ", of the component " + c + " is not found." + " The component is ignored.");
                return null;
            } else {
                LOGGER.log(Level.SEVERE, "The provider class, " + c + ", could not be instantiated. Processing will continue but the class will not be utilized", var6.getTargetException());
                return null;
            }
        } catch (Exception var7) {
            LOGGER.log(Level.SEVERE, "The provider class, " + c + ", could not be instantiated. Processing will continue but the class will not be utilized", var7);
            return null;
        }
    }

配置信息加载

ConfigurationClassEnhancer
- 负责注解Configuration和注解Bean等的实例化,如:
- WebMvcConfigurationSupport根据classpath中是否存在gson、jackson等来
- ArchaiusAutoConfiguration加载archaius配置信息

protected void configureArchaius(ConfigurableEnvironmentConfiguration envConfig) {
    if (initialized.compareAndSet(false, true)) {
        // 获取appName 没有配置则用默认
        String appName = this.env.getProperty("spring.application.name");
        if (appName == null) {
            appName = "application";
            log.warn("No spring.application.name found, defaulting to 'application'");
        }
        // 后面代码省略...    
    }
}    

DefaultListableBeanFactory基于代理实例化eureka组件等,如配置信息,EurekaClient

EurekaClientAutoConfiguration InstanceInfo EurekaClient

EurekaClientConfigBean
SpringCloud对EurekaClient的配置项

EurekaClientAutoConfiguration设置向eureka server或者向其他服务发现组件 注册需要的信息即InstanceInfo,此处为SpringCloud做的适配。

@ProvidedBy(EurekaConfigBasedInstanceInfoProvider.class)
@Serializer("com.netflix.discovery.converters.EntityBodyConverter")
@XStreamAlias("instance")// xml格式的节点
@JsonRootName("instance")// json格式的节点
public class InstanceInfo {
   //代码省略...}

@Bean
@ConditionalOnMissingBean(value = ApplicationInfoManager.class, search = SearchStrategy.CURRENT)
@org.springframework.cloud.context.config.annotation.RefreshScope
@Lazy
public ApplicationInfoManager eurekaApplicationInfoManager(EurekaInstanceConfig config) {
    // 实例化向注册表注册所需要的信息,如eureka主页地址、本机ip、appName等
    InstanceInfo instanceInfo = new InstanceInfoFactory().create(config);
    return new ApplicationInfoManager(config, instanceInfo);
}

EurekaClientAutoConfiguration实例化EurekaClient,设置配置信息,PropertyBasedClientConfigConstants为配置变量名,以及一些默认值,实现类为DiscoveryClient
- EurekaClientAutoConfiguration 源码


@Bean(destroyMethod = "shutdown")
@ConditionalOnMissingBean(value = EurekaClient.class, search = SearchStrategy.CURRENT)
@org.springframework.cloud.context.config.annotation.RefreshScope
@Lazy
public EurekaClient eurekaClient(ApplicationInfoManager manager, EurekaClientConfig config, EurekaInstanceConfig instance) {
    manager.getInfo(); // force initialization
    return new CloudEurekaClient(manager, config, this.optionalArgs,
                    this.context);
}

也会通过EurekaAutoServiceRegistration,将服务自动注册到SpringCloud的服务发现注册框架,定时进行健康检查。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值