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. 著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章