(一)Spring-Cloud源码分析之核心流程关系及springcloud与springboot包区别(新)

文章目录

  • 1. 前言
  • 2. springcloud简介
  • 3. Springcloud包简介
  • 4. Springcloud和Springboot流程关系
  • 5. Springcloud启动流程新增的功能和接口
    • 5.1 新增接口
    • 5.2 新增功能类
      • 5.2.1 spring-cloud-context包
      • 5.2.2 spring-cloud-commons包
  • 6. Springcloud实现机制带来的问题
  • 7. Springcloud和Springboot简单的性能差异对比

1. 前言

在2022年3月份,当时对Springcloud做了很简单的分析,在2023年看来当初那篇文章分析的太过表面,讲述的内容也不是很全面,因此在这里重新做一次回顾,新增修改一些文章内容。

2. springcloud简介

Springcloud在Springboot的基础上新增了对分布式框架的支持,如下:

  • 服务发现注册:Eureka、Zookeeper的starter包;
  • 配置中心:Springcloud Config,平替为流行的Nacos和Apollo;
  • 熔断降级和限流:官方的Hystrix和阿里的Sentinel;
  • 负载均衡:Ribbon+Feign组合;
  • 服务网关:Springcloud Gateway或Zuul

Springcloud需要依赖于Springboot,因此想要玩转Springcloud,前提是对Springboot很熟悉,否则很容易对功能边界模糊不清。

3. Springcloud包简介

Springcloud的依赖管理包这次选用的是Greenwich.SR2,依赖如下:

<dependency>
    <groupId>org.springframework.cloudgroupId>
    <artifactId>spring-cloud-dependenciesartifactId>
    <version>Greenwich.SR3version>
    <type>pomtype>
    <scope>importscope>
dependency>

依赖中主要有Springcloud的通用包:

  • spring-cloud-commons:制定微服务中的服务注册、发现、负载均衡和熔断器等功能的抽象层代码;
  • spring-cloud-context:引入spring-cloud的上下文及接入springboot的一系列插件,用以支持bootstrap文件的读取、上下文刷新等机制的引入;
  • spring-cloud-loadbalancer:负载均衡相关功能。

除了上面三个通用包外,还支持Springcloud其它体系的依赖:

spring-cloud-netflix
spring-cloud-stream
spring-cloud-task
spring-cloud-config
spring-cloud-function
spring-cloud-gateway
spring-cloud-consul
spring-cloud-sleuth
spring-cloud-vault
spring-cloud-zookeeper
spring-cloud-security
spring-cloud-cloudfoundry
spring-cloud-bus
spring-cloud-contract
spring-cloud-aws
spring-cloud-openfeign
spring-cloud-kubernetes
spring-cloud-gcp

这些就不一一介绍了,都是一些Springcloud官方支持的依赖包,如对应功能的starter、core等包。

4. Springcloud和Springboot流程关系

在Springcloudspring-cloud-context包中的spring.factories文件中有ApplicationListener=BootstrapApplicationListener,Springcloud就是以这个类为入口开启了Springcloud的启动流程。如下图:

(一)Spring-Cloud源码分析之核心流程关系及springcloud与springboot包区别(新)_第1张图片

当Springboot完成创建Environment对象后会发布ApplicationEnvironmentPreparedEvent事件,BootstrapApplicationListener便是监听该事件启动Springcloud的启动流程。

从上图也能看出来Springboot和Springcloud的核心启动流程基本一致,且Springcloud大量复用了Springboot放开的接口来实现支持微服务框架。在Springcloud中会存在两个ApplicationContext,两者为父子关系,Springcloud的ApplicationContext为父,Springboot的ApplicationContext为子。

所以从整体上来看,Springcloud是以Springboot放开的ApplicationListener接口为起点,在Springboot的基础上再搭建了一个父ApplicationContext,以这样的结构去扩展Cloud相关框架,并不影响原Springboot的流程。

5. Springcloud启动流程新增的功能和接口

5.1 新增接口

Springcloud在原来Springboot的基础上新增了BootstrapConfigurationSPI机制接口,在BootstrapApplicationListener类中完成加载,并在Springcloud的ApplicationContext刷新流程中完成Import解析。

在spring.factories文件中配置如下:

# Bootstrap components
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration,\
org.springframework.cloud.bootstrap.encrypt.EncryptionBootstrapConfiguration,\
org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration
  1. PropertySourceBootstrapConfiguration:用于配置使用PropertySourceLocator接口的实现类,其作用便是根据Environment对象生成PropertySource对象,并最终保存在bootstrapProperties属性对象中;
  2. EncryptionBootstrapConfiguration:用于配置对Environment对象中的属性进行加解密;
  3. ConfigurationPropertiesRebinderAutoConfiguration:自动注入类,在前面的EnableAutoConfiguration配置项中已经有了,这里重新配置了一下,个人猜测的目的是用于重新绑定spring-cloud上下文,毕竟EnableAutoConfiguration中的配置是针对springboot上下文的;
  4. PropertyPlaceholderAutoConfiguration:引入PropertySourcesPlaceholderConfigurer类,保证springcloud上下文可以使用通配符去替换值。

5.2 新增功能类

5.2.1 spring-cloud-context包

EnableAutoConfiguration自动注入类:

# AutoConfiguration
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration,\
org.springframework.cloud.autoconfigure.LifecycleMvcEndpointAutoConfiguration,\
org.springframework.cloud.autoconfigure.RefreshAutoConfiguration,\
org.springframework.cloud.autoconfigure.RefreshEndpointAutoConfiguration,\
org.springframework.cloud.autoconfigure.WritableEnvironmentEndpointAutoConfiguration
  1. ConfigurationPropertiesRebinderAutoConfiguration:用于自动装填springcloud的重绑定类,用于在springcloud上下文刷新时重新绑定各个bean对象和属性;
  2. LifecycleMvcEndpointAutoConfiguration:用于自动注入EnvironmentManager类;
  3. RefreshAutoConfiguration:自动注入springcloud上下文刷新类,springcloud的RefreshScope和RefreshEventListener等刷新组建便是在这里面被注入的;
  4. RefreshEndpointAutoConfiguration:用于注入刷新Endpoint切点的自动刷新注入类;
  5. WritableEnvironmentEndpointAutoConfiguration:用于自动注入WritableEnvironmentEndpoint类。

ApplicationListener程序监听器类:

# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.cloud.bootstrap.BootstrapApplicationListener,\
org.springframework.cloud.bootstrap.LoggingSystemShutdownListener,\
org.springframework.cloud.context.restart.RestartListener
  1. BootstrapApplicationListener:用于引入springcloud上下文和springcloud自定义配置类,同时也负责生成springcloud上下文对象,并将其设置为springboot的父上下文,也可以通过属性配置这个类不进行加载;
  2. LoggingSystemShutdownListener:负责清空前面设置过的Log日志信息,以避免后续的日志加载收到前面日志配置的影响;
  3. RestartListener:保存spring的上下文,以便后续在有必要的时候重启上下文。

5.2.2 spring-cloud-commons包

EnableAutoConfiguration自动注入类:

# AutoConfiguration
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.client.CommonsClientAutoConfiguration,\
org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClientAutoConfiguration,\
org.springframework.cloud.client.discovery.noop.NoopDiscoveryClientAutoConfiguration,\
org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClientAutoConfiguration,\
org.springframework.cloud.client.hypermedia.CloudHypermediaAutoConfiguration,\
org.springframework.cloud.client.loadbalancer.AsyncLoadBalancerAutoConfiguration,\
org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration,\
org.springframework.cloud.client.loadbalancer.reactive.ReactorLoadBalancerClientAutoConfiguration,\
org.springframework.cloud.client.loadbalancer.reactive.ReactiveLoadBalancerAutoConfiguration,\
org.springframework.cloud.client.serviceregistry.ServiceRegistryAutoConfiguration,\
org.springframework.cloud.commons.httpclient.HttpClientConfiguration,\
org.springframework.cloud.commons.util.UtilAutoConfiguration,\
org.springframework.cloud.configuration.CompatibilityVerifierAutoConfiguration,\
org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationAutoConfiguration

可以看到相对于spring-cloud-context而言自动注入类的配置项是非常多的,而且从名字也可以看出来这是用来进行服务注册、发现及负载均衡相关的。大致作用:

  1. CommonsClientAutoConfiguration:用来自动注册通用的客户端组件,如健康检查及Endpoint切点的组件对象;
  2. CompositeDiscoveryClientAutoConfiguration:注册用来保存多种DiscoveryClient对象类型的对象CompositeDiscoveryClient;
  3. NoopDiscoveryClientAutoConfiguration:注册一个实现了DiscoveryClient接口,用来代表基础机器信息NoopDiscoveryClient类型对象;
  4. SimpleDiscoveryClientAutoConfiguration:注册SimpleDiscoveryProperties对象及相关的其它对象,在前面注册过的NoopDiscoveryClient基础上新增SimpleDiscoveryClient类型的对象;
  5. CloudHypermediaAutoConfiguration:注册用来管理和刷新远程资源的相关对象;
  6. AsyncLoadBalancerAutoConfiguration:注册Ribbon相关的异步负载均衡相关配置类;
  7. LoadBalancerAutoConfiguration:注册Ribbon相关的同步负载均衡和重试机制相关配置类;
  8. ReactorLoadBalancerClientAutoConfiguration:用来注册@LoadBalanced注解及ReactiveLoadBalancer等负载均衡类;
  9. ReactiveLoadBalancerAutoConfiguration:为Reactor自动注入类的辅助类;
  10. ServiceRegistryAutoConfiguration:自动注入服务注册切点相关类;
  11. HttpClientConfiguration:自动注入http相关的实现类,支持okhttp和apache;
  12. UtilAutoConfiguration:注册提供通用方法的类,如InetUtilsProperties和InetUtils;
  13. CompatibilityVerifierAutoConfiguration:自动注入系统的校验类,如校验springboot版本和springcloud版本是否兼容的SpringBootVersionVerifier,以及可以保存其它校验类的可组合式CompositeCompatibilityVerifier;
  14. AutoServiceRegistrationAutoConfiguration:自动发现服务注入类,用来校验自动注入相关功能是否正常执行,如果没有则抛异常。

上面十四个都是大概的描述了其中的功能,里面用到了很多的@Autowired注解,因此如果程序后续注入了相关的实现类都会被注入,这也是为何把这个包称为springcloud微服务注册发现的抽象层,因为后续只要有相关的实现接入,便可以自动装填运行,方式比较新颖。

EnvironmentPostProcessor环境对象后处理器:

spring.factories文件中对于EnvironmentPostProcessor选项只有一个实现配置类:

  • HostInfoEnvironmentPostProcessor:用来在环境对象中生成springCloudClientHostInfo属性信息,这里面包括了本机器的IP地址和主机名称信息,用来提供机器的身份证明。

FailureAnalyzer启动错误分析类:

spring.factories对于FailureAnalyzer也只有一个实现配置类:

  • CompatibilityNotMetFailureAnalyzer:用来组织程序发生错误时的输出内容。

6. Springcloud实现机制带来的问题

Springcloud由于是在原Springboot的基础上新建了一个父ApplicationContext,因此SPI机制上会进行重复读取,导致父子两个ApplicationContext都含有一模一样的SPI实现类,SPI实现类就会执行两次。

7. Springcloud和Springboot简单的性能差异对比

差异对比springboot依赖如下:

<parent>
    
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-parentartifactId>
    <version>2.1.6.RELEASEversion>
parent>

<dependencies>
    
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-webartifactId>
    dependency>

    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-testartifactId>
    dependency>
dependencies>

差异对比springcloud依赖如下:

<parent>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-parentartifactId>
    <version>2.1.6.RELEASEversion>
parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.cloudgroupId>
        <artifactId>spring-cloud-starterartifactId>
        <version>2.1.2.RELEASEversion>
    dependency>

    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-webartifactId>
    dependency>

    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-testartifactId>
    dependency>
dependencies>

项目只有一个controller,单纯的启动springboot和springcloud时间统计表(非严谨):

次数 springboot springcloud
1 1.139 seconds (JVM running for 1.615) 1.695 seconds (JVM running for 2.188)
2 1.145 seconds (JVM running for 1.63) 1.714 seconds (JVM running for 2.221)
3 1.42 seconds (JVM running for 1.942) 1.76 seconds (JVM running for 2.255)
4 1.135 seconds (JVM running for 1.623) 1.74 seconds (JVM running for 2.24)
5 1.133 seconds (JVM running for 1.626) 1.694 seconds (JVM running for 2.308)
6 1.164 seconds (JVM running for 1.658) 1.708 seconds (JVM running for 2.218)
7 1.214 seconds (JVM running for 1.723) 1.715 seconds (JVM running for 2.212)
8 1.164 seconds (JVM running for 1.658) 1.743 seconds (JVM running for 2.259)
9 1.142 seconds (JVM running for 1.636) 1.756 seconds (JVM running for 2.261)
10 1.126 seconds (JVM running for 1.595) 1.701 seconds (JVM running for 2.194)

去掉最高和最低值后平均启动速度如下:

  • springboot:平均启动时间为1.1545s
  • springcloud:平均启动时间为1.7215

springcloud启动时间较springboot时间平均多出0.567s,即567ms,再加上多引入了包,导致JVM启动时间会延长半秒左右,因此使用springcloud会导致整个项目启动时间延迟1s左右,但这个性能消耗完全是可以忽略不计的。

你可能感兴趣的:(#,Springcloud相关,spring,cloud,spring,boot,java)