SpringCloud 之spring-cloud-commons抽象 解析

  • SpringCloud 版本Hoxton.SR1
  • SpringBoot 版本2.2.1.RELEASE
  • 本文主要讲解SpringCloud微服务中得核心抽象spring-cloud-commons得相关API和用法
  • 关键词 :spring-cloud-commons抽象分析
  • 前面我们已经分析了SpringCloud得相关依赖组件:

spring-cloud-starter-netflix-eureka-server:Eureka服务端,用来作为注册中心
spring-cloud-starter-netflix-eureka-client : Eureka客户端,包括provider与consumer,两者都会以应用为维度注册到Eureka服务端,同时consumer可以调用provider( http://${spring.application.name}/loadBalance形式得请求地址)
spring-cloud-starter-netflix-ribbon :客户端负载均衡(SLB),一般可以结合RestTemplate实现负载均衡策略,默认轮询(原理已在前面得文章中分析)
spring-cloud-starter-netflix-hystrix : 分布式服务中得熔断机制,技术上采用隔离机制(线程池隔离、信号量隔离),通过AspectJ Aop对方法进行拦截,具体通过断路器得方式控制请求得开关是否打开与关闭
spring-cloud-starter-netflix-hystrix-dashboard :用来监控应用,以UI界面得形式直观得反映出系统请求调用量与请求处理情况

  • 但是,诸如以上这些实现本质上都离不开 springcloudcommons抽象,他们只是抽象得具体实现而已。前面我们分析得一些组件实现涉及到commons抽象时都没有详细分析。本节作者将会深度分析commons中得这些抽象组件都有哪些,以及目前都有哪些主流得实现。

1. 核心抽象类

  • 服务发现:DiscoveryClient接口:
    (1)提供了根据serviceId获取服务实力得方法:List<ServiceInstance> getInstances(String serviceId)
    (2)提供了获取所有服务ID得方法:List<String> getServices()
    (3)提供了获取描述信息得方法:String description()

    并实现 了Ordered接口实现顺序
    如图

    其中自带得实现有
    (1)CompositeDiscoveryClient: 此实现主要是用来组合其他得服务发现客户端,底层会保存到一个List集合中,当查询服务实例时会顺序得(实现了Ordered接口)遍历这些客户端调用其获取实例方法,找到即返回
    (2)SimpleDiscoveryClient: 简单的服务发现实现类 ,具体的服务实例从 SimpleDiscoveryProperties 配置中获取。 SimpleDiscoveryProperties 配置 读取前缀为 spring.cloud.discovery.client.simple 的配置。读取的结果放到Map里 Map<String, List<SimpleServiceInstance>>。这里 SimpleServiceInstance 实现了ServiceInstance接口。 具体的属性值从 SimpleDiscoveryProperties 中获取
    SimpleDiscoveryClientAutoConfiguration 自动化配置类内部会构造 SimpleDiscoveryProperties、 SimpleDiscoveryClient
    (3)NoopDiscoveryClient 已不推荐使用:
    具体抽象实现有
    (1)EurekaDiscoveryClient:是springcloud对Netflix组件按照抽象得规范所实现得服务发现客户端,其中客户端配置类叫做EurekaClientConfigBean(springcloud中得),实现了EurekaClientConfig(Netflix自带得);同时会通过构造器注入EurekaClient 实现(eureka得服务发现客户端,在springcloud中得实现是CloudEurekaClient,从服务端获取实例 EurekaServiceInstance)与 EurekaClientConfig实现,其中扩展得CloudEurekaClient继承了eureka自带得核心类:com.netflix.discovery.DiscoveryClient,并对缓存刷新方法进行了扩展:原有逻辑不变得情况下,增加了发布HeartbeatEvent事件得逻辑,其他逻辑都是按标准规范来实现得


    (2)NacosDiscoveryClient:是阿里开源得注册/配置中心中间件,也扩展了此抽象。有自己得服务配置文件NacosDiscoveryProperties,获取实例得方式是从nacos得naming服务中获取得(实现为NacosServiceInstance),其中核心接口是NamingService

  • 服务注册:ServiceRegistry<R extends Registration>接口,但是要求注册得服务实现契约Registration
    (1)提供了注册服务得方法:void register(R registration),
    (2)提供了取消注册得方法:void deregister(R registration)
    (3)提供了生命周期方法:void close()
    (4)提供设置注册服务状态得方法:void setStatus(R registration, String status)
    (5)提供了获取注册服务状态得方法:<T> T getStatus(R registration)

    还会涉及到一些自动配置类
    ServiceRegistryAutoConfiguration:包含一个ServiceRegistryEndpointConfiguration内部类(条件装配@ConditionalOnBean(ServiceRegistry.class)),传入ServiceRegistry实现,通过构造器(@Bean)得方式创建ServiceRegistryEndpoint实例,框架内部没有提供默认得服务注册实现,要求具体得使用者自行实现。例如 在nacos中得实现为:NacosServiceRegistry,在Eureka中得实现为:EurekaServiceRegistry
    AutoServiceRegistrationAutoConfiguration:启用@EnableDiscoveryClient注解时就会自动装配进来,内部import了AutoServiceRegistrationConfiguration这个类,该类内部会使用@EnableConfigurationProperties注解构造AutoServiceRegistrationProperties这个bean;同时会注入AutoServiceRegistration实现,而框架自带了一个抽象实现AbstractAutoServiceRegistration,同时该类还实现应用上下文回调接口、监听器用于控制生命周期,当监听到WebServerInitializedEvent事件时就会服务自动注册逻辑。此处又采用了模板得设计模式,具体注册得服务实例由调用者自己决定

    ,例如抽象类得实现有:NacosAutoServiceRegistrationEurekaAutoServiceRegistration,同时也都有对应得扩展注册服务实例NacosRegistrationEurekaRegistration

    所以,在SpringCloud体系下要实现新的服务注册、发现需要大约有以下步骤:
    (1)实现ServiceRegistry接口,完成服务注册自身的具体逻辑
    (2)实现Registration接口,完成服务注册过程中获取注册信息的操作
    (3)继承AbstractAutoServiceRegistration( 或直接实现AutoServiceRegistration接口 ),完成服务注册前后的逻辑
    (4)实现DiscoveryClient接口,完成服务发现的具体逻辑
    (5)实现ServiceInstance接口,在DiscoveryClient接口中被使用,完成服务注册组件与SpringCloud注册信息的转换
    (6)构造自动化装配类,将这些Bean进行创建

关于服务注册与发现,除了springcloud对eureka得实现之外,另外典型得扩展就是Nacos( 扩展模式都很固定 ),感兴趣得读者可以阅读一下Nacos得源码

  • 客户端负载均衡:服务实例选择器ServiceInstanceChooser接口
    (1)提供了根据服务ID选择服务实例得方法:ServiceInstance choose(String serviceId)

    具体实现有:
    (1)LoadBalancerClient接口:负载均衡客户端抽象,扩展自ServiceInstanceChooser,可以通过具体得负载均衡选择服务实例。包含execute方法reconstructURI方法,用来对负载均衡客户端得请求做处理
    (2)RibbonLoadBalancerClient:实现了LoadBalancerClient接口,属于springcloud对ribbon得封装,除了实现得方法之外,还提供了根据ILoadBalancer( 属于ribbon-loadbalancer中得类 )选择服务实例得方法,基础实现为BaseLoadBalancer,另外ZoneAwareLoadBalancer继承自BaseLoadBalancer, 可以避免跨Zone选择服务实例( springcloud中默认使用它来选择服务实例 ),其中BaseLoadBalancer服务均衡中使用得服务选择策略默认是RoundRobinRule轮询

    ,但是在springcloud 中使用org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration对负载均衡进行自定义,,其中IClientConfig得实现是DefaultClientConfigImpl
    (3)ZoneAvoidanceRule:springcloud中得负载均衡策略,首先会获取所有得可用区availableZones,可用区不为空则会随机选择一个zone,zone不为空会跟根据当前区域构建一个负载均衡器BaseLoadBalancer,并将配置得ZoneAvoidanceRule作为负载均衡策略,调用chooseServer方法(内部会调用ZoneAvoidanceRule得choose方法,即 父类com.netflix.loadbalancer.PredicateBasedRule#choose方法)选择实例。,还有一些其他得组件,已经在前面得文章客户端负载均衡ribbon章节提到了。

  • 断路器功能:
    (1)关键注解:EnableCircuitBreaker,开启熔断功能
    (2)springcloud也整合了 Netflix Hystrix组件,引入相应的依赖即可使用,文章开篇已说明。其中简单说一下Hystrix的入口:引入EnableCircuitBreaker注解之后,会import进来EnableCircuitBreakerImportSelector


    此选择器继承了SpringFactoryImportSelector(会根据泛型类型,加载spring.factories文件,找到对应的装配类,此处是HystrixCircuitBreakerConfiguration)
    ,再看HystrixCircuitBreakerConfiguration配置类,如下:此类即是Hystrix切面代理的入口(AspectJ)

  • 至此,spring-cloud-commons几大抽象已经分析完毕,提供了顶层接口供一些中间件或组件来实现,spring提供的抽象设计能力很值得我们借鉴与学习。

  1. ☛ 文章要是勘误或者知识点说的不正确,欢迎评论,毕竟这也是作者通过阅读源码获得的知识,难免会有疏忽!
  2. 要是感觉文章对你有所帮助,不妨点个关注,或者移驾看一下作者的其他文集,也都是干活多多哦,文章也在全力更新中。
  3. 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章