- 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
事件时就会服务自动注册逻辑。此处又采用了模板得设计模式,具体注册得服务实例由调用者自己决定NacosAutoServiceRegistration
、EurekaAutoServiceRegistration
,同时也都有对应得扩展注册服务实例NacosRegistration
、EurekaRegistration
所以,在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
轮询org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration
对负载均衡进行自定义,IClientConfig得实现是DefaultClientConfigImpl
(3)ZoneAvoidanceRule
:springcloud中得负载均衡策略,首先会获取所有得可用区availableZones,可用区不为空则会随机选择一个zone,zone不为空会跟根据当前区域构建一个负载均衡器BaseLoadBalancer,并将配置得ZoneAvoidanceRule作为负载均衡策略,调用chooseServer方法(内部会调用ZoneAvoidanceRule得choose方法,即父类com.netflix.loadbalancer.PredicateBasedRule#choose方法
)选择实例。 -
断路器功能:
(1)关键注解:EnableCircuitBreaker
,开启熔断功能
(2)springcloud也整合了 Netflix Hystrix组件,引入相应的依赖即可使用,文章开篇已说明。其中简单说一下Hystrix的入口:引入EnableCircuitBreaker注解之后,会import进来EnableCircuitBreakerImportSelector
,
此选择器继承了SpringFactoryImportSelector(会根据泛型类型,加载spring.factories文件,找到对应的装配类,此处是HystrixCircuitBreakerConfiguration)
此类即是Hystrix切面代理的入口(AspectJ)
至此,spring-cloud-commons几大抽象已经分析完毕,提供了顶层接口供一些中间件或组件来实现,spring提供的抽象设计能力很值得我们借鉴与学习。
- ☛ 文章要是勘误或者知识点说的不正确,欢迎评论,毕竟这也是作者通过阅读源码获得的知识,难免会有疏忽!
- ☛ 要是感觉文章对你有所帮助,不妨点个关注,或者移驾看一下作者的其他文集,也都是干活多多哦,文章也在全力更新中。
- ☛ 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处!