- SpringCloud 版本 :Hoxton.SR1
- SpringBoot 版本:2.2.1.RELEASE
- 本文主要講解SpringCloud微服務(wù)中得核心抽象spring-cloud-commons得相關(guān)API和用法
- 關(guān)鍵詞 :spring-cloud-commons抽象分析
- 前面我們已經(jīng)分析了SpringCloud得相關(guān)依賴組件:
spring-cloud-starter-netflix-eureka-server:
Eureka服務(wù)端,用來作為注冊(cè)中心
spring-cloud-starter-netflix-eureka-client :Eureka客戶端,包括provider與consumer,兩者都會(huì)以應(yīng)用為維度注冊(cè)到Eureka服務(wù)端,同時(shí)consumer可以調(diào)用provider( http://${spring.application.name}/loadBalance形式得請(qǐng)求地址)
spring-cloud-starter-netflix-ribbon :客戶端負(fù)載均衡(SLB),一般可以結(jié)合RestTemplate實(shí)現(xiàn)負(fù)載均衡策略,默認(rèn)輪詢(原理已在前面得文章中分析)
spring-cloud-starter-netflix-hystrix :分布式服務(wù)中得熔斷機(jī)制,技術(shù)上采用隔離機(jī)制(線程池隔離、信號(hào)量隔離),通過AspectJ Aop對(duì)方法進(jìn)行攔截,具體通過斷路器得方式控制請(qǐng)求得開關(guān)是否打開與關(guān)閉
spring-cloud-starter-netflix-hystrix-dashboard :用來監(jiān)控應(yīng)用,以UI界面得形式直觀得反映出系統(tǒng)請(qǐng)求調(diào)用量與請(qǐng)求處理情況
- 但是,諸如以上這些實(shí)現(xiàn)本質(zhì)上都離不開 springcloudcommons抽象,他們只是抽象得具體實(shí)現(xiàn)而已。前面我們分析得一些組件實(shí)現(xiàn)涉及到commons抽象時(shí)都沒有詳細(xì)分析。本節(jié)作者將會(huì)深度分析commons中得這些抽象組件都有哪些,以及目前都有哪些主流得實(shí)現(xiàn)。
1. 核心抽象類
-
服務(wù)發(fā)現(xiàn):
DiscoveryClient接口:
(1)提供了根據(jù)serviceId獲取服務(wù)實(shí)力得方法:List<ServiceInstance> getInstances(String serviceId)
(2)提供了獲取所有服務(wù)ID得方法:List<String> getServices()
(3)提供了獲取描述信息得方法:String description()
并實(shí)現(xiàn) 了Ordered接口實(shí)現(xiàn)順序
如圖:DiscoveryClient得實(shí)現(xiàn)其中自帶得實(shí)現(xiàn)有:
(1)CompositeDiscoveryClient: 此實(shí)現(xiàn)主要是用來組合其他得服務(wù)發(fā)現(xiàn)客戶端,底層會(huì)保存到一個(gè)List集合中,當(dāng)查詢服務(wù)實(shí)例時(shí)會(huì)順序得(實(shí)現(xiàn)了Ordered接口)遍歷這些客戶端調(diào)用其獲取實(shí)例方法,找到即返回
(2)SimpleDiscoveryClient: 簡(jiǎn)單的服務(wù)發(fā)現(xiàn)實(shí)現(xiàn)類 ,具體的服務(wù)實(shí)例從SimpleDiscoveryProperties配置中獲取。 SimpleDiscoveryProperties 配置 讀取前綴為 spring.cloud.discovery.client.simple 的配置。讀取的結(jié)果放到Map里 Map<String, List<SimpleServiceInstance>>。這里SimpleServiceInstance實(shí)現(xiàn)了ServiceInstance接口。 具體的屬性值從 SimpleDiscoveryProperties 中獲取
SimpleDiscoveryClientAutoConfiguration自動(dòng)化配置類內(nèi)部會(huì)構(gòu)造 SimpleDiscoveryProperties、 SimpleDiscoveryClient
(3)NoopDiscoveryClient已不推薦使用:
具體抽象實(shí)現(xiàn)有:
(1)EurekaDiscoveryClient:是springcloud對(duì)Netflix組件按照抽象得規(guī)范所實(shí)現(xiàn)得服務(wù)發(fā)現(xiàn)客戶端,其中客戶端配置類叫做EurekaClientConfigBean(springcloud中得),實(shí)現(xiàn)了EurekaClientConfig(Netflix自帶得);同時(shí)會(huì)通過構(gòu)造器注入EurekaClient實(shí)現(xiàn)(eureka得服務(wù)發(fā)現(xiàn)客戶端,在springcloud中得實(shí)現(xiàn)是CloudEurekaClient,從服務(wù)端獲取實(shí)例 EurekaServiceInstance)與EurekaClientConfig實(shí)現(xiàn),其中擴(kuò)展得CloudEurekaClient繼承了eureka自帶得核心類:com.netflix.discovery.DiscoveryClient,并對(duì)緩存刷新方法進(jìn)行了擴(kuò)展:原有邏輯不變得情況下,增加了發(fā)布HeartbeatEvent事件得邏輯,其他邏輯都是按標(biāo)準(zhǔn)規(guī)范來實(shí)現(xiàn)得org.springframework.cloud.netflix.eureka.CloudEurekaClient#onCacheRefreshed
(2)NacosDiscoveryClient:是阿里開源得注冊(cè)/配置中心中間件,也擴(kuò)展了此抽象。有自己得服務(wù)配置文件NacosDiscoveryProperties,獲取實(shí)例得方式是從nacos得naming服務(wù)中獲取得(實(shí)現(xiàn)為NacosServiceInstance),其中核心接口是NamingService -
服務(wù)注冊(cè):
ServiceRegistry<R extends Registration>接口,但是要求注冊(cè)得服務(wù)實(shí)現(xiàn)契約Registration
(1)提供了注冊(cè)服務(wù)得方法:void register(R registration),
(2)提供了取消注冊(cè)得方法:void deregister(R registration)
(3)提供了生命周期方法:void close()
(4)提供設(shè)置注冊(cè)服務(wù)狀態(tài)得方法:void setStatus(R registration, String status)
(5)提供了獲取注冊(cè)服務(wù)狀態(tài)得方法:<T> T getStatus(R registration)
還會(huì)涉及到一些自動(dòng)配置類:
①ServiceRegistryAutoConfiguration:包含一個(gè)ServiceRegistryEndpointConfiguration內(nèi)部類(條件裝配@ConditionalOnBean(ServiceRegistry.class)),傳入ServiceRegistry實(shí)現(xiàn),通過構(gòu)造器(@Bean)得方式創(chuàng)建ServiceRegistryEndpoint實(shí)例,框架內(nèi)部沒有提供默認(rèn)得服務(wù)注冊(cè)實(shí)現(xiàn),要求具體得使用者自行實(shí)現(xiàn)。例如 在nacos中得實(shí)現(xiàn)為:NacosServiceRegistry,在Eureka中得實(shí)現(xiàn)為:EurekaServiceRegistry
②AutoServiceRegistrationAutoConfiguration:?jiǎn)⒂?code>@EnableDiscoveryClient注解時(shí)就會(huì)自動(dòng)裝配進(jìn)來,內(nèi)部import了AutoServiceRegistrationConfiguration這個(gè)類,該類內(nèi)部會(huì)使用@EnableConfigurationProperties注解構(gòu)造AutoServiceRegistrationProperties這個(gè)bean;同時(shí)會(huì)注入AutoServiceRegistration實(shí)現(xiàn),而框架自帶了一個(gè)抽象實(shí)現(xiàn)AbstractAutoServiceRegistration,同時(shí)該類還實(shí)現(xiàn)應(yīng)用上下文回調(diào)接口、監(jiān)聽器用于控制生命周期,當(dāng)監(jiān)聽到WebServerInitializedEvent事件時(shí)就會(huì)服務(wù)自動(dòng)注冊(cè)邏輯。此處又采用了模板得設(shè)計(jì)模式,具體注冊(cè)得服務(wù)實(shí)例由調(diào)用者自己決定,例如抽象類得實(shí)現(xiàn)有:抽象類AbstractAutoServiceRegistration得register相關(guān)邏輯NacosAutoServiceRegistration、EurekaAutoServiceRegistration,同時(shí)也都有對(duì)應(yīng)得擴(kuò)展注冊(cè)服務(wù)實(shí)例NacosRegistration、EurekaRegistration
com.alibaba.cloud.nacos.registry.NacosAutoServiceRegistrationorg.springframework.cloud.netflix.eureka.serviceregistry.EurekaAutoServiceRegistration
所以,在SpringCloud體系下要實(shí)現(xiàn)新的服務(wù)注冊(cè)、發(fā)現(xiàn)需要大約有以下步驟:
(1)實(shí)現(xiàn)ServiceRegistry接口,完成服務(wù)注冊(cè)自身的具體邏輯
(2)實(shí)現(xiàn)Registration接口,完成服務(wù)注冊(cè)過程中獲取注冊(cè)信息的操作
(3)繼承AbstractAutoServiceRegistration( 或直接實(shí)現(xiàn)AutoServiceRegistration接口 ),完成服務(wù)注冊(cè)前后的邏輯
(4)實(shí)現(xiàn)DiscoveryClient接口,完成服務(wù)發(fā)現(xiàn)的具體邏輯
(5)實(shí)現(xiàn)ServiceInstance接口,在DiscoveryClient接口中被使用,完成服務(wù)注冊(cè)組件與SpringCloud注冊(cè)信息的轉(zhuǎn)換
(6)構(gòu)造自動(dòng)化裝配類,將這些Bean進(jìn)行創(chuàng)建
關(guān)于服務(wù)注冊(cè)與發(fā)現(xiàn),除了springcloud對(duì)eureka得實(shí)現(xiàn)之外,另外典型得擴(kuò)展就是Nacos( 擴(kuò)展模式都很固定 ),感興趣得讀者可以閱讀一下Nacos得源碼
-
客戶端負(fù)載均衡:服務(wù)實(shí)例選擇器
ServiceInstanceChooser接口
(1)提供了根據(jù)服務(wù)ID選擇服務(wù)實(shí)例得方法:ServiceInstance choose(String serviceId)
具體實(shí)現(xiàn)有:
(1)LoadBalancerClient接口:負(fù)載均衡客戶端抽象,擴(kuò)展自ServiceInstanceChooser,可以通過具體得負(fù)載均衡選擇服務(wù)實(shí)例。包含execute方法、reconstructURI方法,用來對(duì)負(fù)載均衡客戶端得請(qǐng)求做處理
(2)RibbonLoadBalancerClient:實(shí)現(xiàn)了LoadBalancerClient接口,屬于springcloud對(duì)ribbon得封裝,除了實(shí)現(xiàn)得方法之外,還提供了根據(jù)ILoadBalancer( 屬于ribbon-loadbalancer中得類 )選擇服務(wù)實(shí)例得方法,基礎(chǔ)實(shí)現(xiàn)為BaseLoadBalancer,另外ZoneAwareLoadBalancer繼承自BaseLoadBalancer, 可以避免跨Zone選擇服務(wù)實(shí)例(springcloud中默認(rèn)使用它來選擇服務(wù)實(shí)例),其中BaseLoadBalancer服務(wù)均衡中使用得服務(wù)選擇策略默認(rèn)是RoundRobinRule輪詢com.netflix.loadbalancer.BaseLoadBalancer#chooseServer,但是在springcloud 中使用com.netflix.loadbalancer.BaseLoadBalancerorg.springframework.cloud.netflix.ribbon.RibbonClientConfiguration對(duì)負(fù)載均衡進(jìn)行自定義,,其中org.springframework.cloud.netflix.ribbon.RibbonClientConfigurationIClientConfig得實(shí)現(xiàn)是DefaultClientConfigImpl
(3)ZoneAvoidanceRule:springcloud中得負(fù)載均衡策略,首先會(huì)獲取所有得可用區(qū)availableZones,可用區(qū)不為空則會(huì)隨機(jī)選擇一個(gè)zone,zone不為空會(huì)跟根據(jù)當(dāng)前區(qū)域構(gòu)建一個(gè)負(fù)載均衡器BaseLoadBalancer,并將配置得ZoneAvoidanceRule作為負(fù)載均衡策略,調(diào)用chooseServer方法(內(nèi)部會(huì)調(diào)用ZoneAvoidanceRule得choose方法,即父類com.netflix.loadbalancer.PredicateBasedRule#choose方法)選擇實(shí)例。,還有一些其他得組件,已經(jīng)在前面得文章客戶端負(fù)載均衡ribbon章節(jié)提到了。com.netflix.loadbalancer.PredicateBasedRule -
斷路器功能:
(1)關(guān)鍵注解:EnableCircuitBreaker,開啟熔斷功能
(2)springcloud也整合了 Netflix Hystrix組件,引入相應(yīng)的依賴即可使用,文章開篇已說明。其中簡(jiǎn)單說一下Hystrix的入口:引入EnableCircuitBreaker注解之后,會(huì)import進(jìn)來EnableCircuitBreakerImportSelector,org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker
此選擇器繼承了SpringFactoryImportSelector(會(huì)根據(jù)泛型類型,加載spring.factories文件,找到對(duì)應(yīng)的裝配類,此處是HystrixCircuitBreakerConfiguration)org.springframework.cloud.client.circuitbreaker.EnableCircuitBreakerImportSelector
,再看HystrixCircuitBreakerConfiguration配置類,如下:spring-cloud-netflix-hystrix依賴下面的spring.factories文件,org.springframework.cloud.netflix.hystrix.HystrixCircuitBreakerConfiguration此類即是Hystrix切面代理的入口(AspectJ) 至此,spring-cloud-commons幾大抽象已經(jīng)分析完畢,提供了頂層接口供一些中間件或組件來實(shí)現(xiàn),spring提供的抽象設(shè)計(jì)能力很值得我們借鑒與學(xué)習(xí)。
- ? 文章要是勘誤或者知識(shí)點(diǎn)說的不正確,歡迎評(píng)論,畢竟這也是作者通過閱讀源碼獲得的知識(shí),難免會(huì)有疏忽!
- ? 要是感覺文章對(duì)你有所幫助,不妨點(diǎn)個(gè)關(guān)注,或者移駕看一下作者的其他文集,也都是干活多多哦,文章也在全力更新中。
- ? 著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處!












