天天看點

分布式微服務治理

文章目錄

    • 什麼是微服務架構
    • 為什麼要使用微服務
    • SpringCloud
      • 服務注冊發現
        • Eureka
      • 服務熔斷降級
        • Hystrix
      • 服務網關
        • GetWay
      • 服務調用
        • OpenFeign
      • 服務負載
        • Ribbon
      • 服務配置中心
        • SpringCloud Config
      • 服務開發
        • SpringBoot

什麼是微服務架構

In short, the microservice architectural style is an approach to developing a single application as a suite of small services,

each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API.

These services are built around business capabilities and independently deployable by fully automated deployment machinery.

There is a bare minimum of centralized management of these services, which may be written in different programming languages and use different data storage technologies. ——James Lewis and Martin Fowler (2014)

大意:簡而言之,微服務體系結構風格是一種将單個應用程式開發為一套小型服務的方法,每個服務運作在自己的程序中,并與輕量級機制(通常是HTTP資源API)通信。

這些服務是圍繞業務功能建構的,可以通過全自動部署機制進行獨立部署。對這些服務的集中管理是最低限度的,這些服務可能用不同的程式設計語言編寫,并使用不同的資料存儲技術。

微服務是一種架構風格,将服務圍繞業務功能拆分,一個應用拆分為一組小型服務,每個服務運作在自己的程序内,也就是可獨立部署和更新,服務之間使用輕量級HTTP互動,可以由全自動部署機制獨立部署,去中心化,服務自治。服務可以使用不同的語言、不同的存儲技術。

為什麼要使用微服務

說的微服務就不得不說微服務之前的單體應用,有對比才能看的出微服務對比之前的單體應用到底強在哪?為什麼我們要抛棄單體應用?

  • 單體應用往往所有的功能打包在一個包裡,包含了 DO/DAO,Service,UI等所有邏輯,如果要修改一部分代碼就需要全部重新部署,是以改動影響大,風險高。微服務模式彌補了這個缺陷,它将應用合理的拆分,實作靈活開發和快速部署。
  • 單體應用隻能通過在負載均衡器後面放置整個應用程式的多個執行個體來進行水準擴充,如果想要擴充特定的程式,顯然是不行的,則需要使用到微服務模式實作。
  • 因為單體應用所有的功能全部都達到一個包裡面,是以耦合性比較強,對于程式員來說代碼維護會收到影響,出現了什麼問題也不太友善進行排查。
  • 如果沒有正确的設計,單體應用的一部分失敗可能會級聯并導緻整個系統崩潰。而這種情況可以使用微服務的熔斷、降級的思想來解決。

微服務雖然好處多多,但是缺點就是服務衆多,治理成本高,不利于維護系統,項目成本會升高,是以項目架構設計時應綜合考量。

建議設計的原則是業務驅動、設計保障、演進式疊代、保守治療的方式。搞不清楚,有争議的地方先盡量不要拆,如果确實要拆,要經過業務分析後慎重設計,把真正相對獨立的部分拆分出來,可以借鑒 DDD 的方式。拆了以後要觀察微服務的接口是否穩定,針對業務需求的變更微服務的子產品是否可以保持相對穩定,是否可以獨立演進。

DDD: Domain-driven design的簡稱,譯為領域驅動設計,是一種通過将實作連接配接到持續進化的模型來滿足複雜需求的軟體開發方法。

核心思想:DDD其實是面向對象方法論的一個升華。無外乎是通過劃分領域(聚合根、實體、值對象)、領域行為封裝到領域對象(充血模式)、内外互動封裝到防腐層、職責封裝到對應的子產品和分層,進而實作了高内聚低耦合。

連結:https://blog.csdn.net/qq_31960623/article/details/119840131

SpringCloud

随着微服務模式的使用,服務之間的調用帶來的問題有很多,例如:資料一緻性、網絡波動、緩存、事務等問題,針對這一系列的問題就要有對應的架構來解決,目前主流一站式微服務解決方案有

Spring Cloud

Spring Cloud Alibaba

Spring Cloud

它并不是一個架構,而是很多個架構。它是分布式微服務架構的一站式解決方案,是多種微服務架構落地技術的集合體,俗稱微服務全家桶。

分布式微服務治理
分布式微服務治理

服務注冊發現

在服務注冊與發現中,有一個注冊中心。當伺服器啟動的時候,會把目前自己伺服器的資訊比如服務位址通訊位址等以别名方式注冊到注冊中心上。另一方消費者服務提供者,以該别名的方式去注冊中心上擷取到實際的服務通訊位址,然後再實作本地RPC調用。RPC遠端調用架構核心設計思想:在于注冊中心,因為使用注冊中心管理每個服務與服務之間的一個依賴關系。在任何RPC遠端架構中,都會有一個注冊中心存放服務位址相關資訊。

Eureka

參考文章:

  • https://www.jianshu.com/p/cb7fa0aa47a8
Eureka is a REST (Representational State Transfer) based service that is primarily used in the AWS cloud for locating services for the purpose of load balancing and failover of middle-tier servers. We call this service, the Eureka Server. Eureka also comes with a Java-based client component,the Eureka Client, which makes interactions with the service much easier. The client also has a built-in load balancer that does basic round-robin load balancing. —https://github.com/Netflix/eureka

大意:Eureka是一個REST (Representational State Transfer)服務,它主要用于AWS雲,用于定位服務,以實作中間層伺服器的負載平衡和故障轉移,我們稱此服務為Eureka伺服器。Eureka也有一個基于java的用戶端元件,Eureka用戶端,這使得與服務的互動更加容易,同時用戶端也有一個内置的負載平衡器,它執行基本的循環負載均衡。

Eureka采用了CS的設計架構,Eureka Sever作為服務注冊功能的伺服器,它是服務注冊中心。而系統中的其他微服務,使用Eureka的用戶端連接配接到 Eureka Server并維持心跳連接配接。這樣系統的維護人員就可以通過Eureka Server來監控系統中各個微服務是否正常運作。

分布式微服務治理
  • Eureka Server 提供服務注冊服務;各個微服務節點通過配置啟動後,會在EurekaServer中進行注冊,這樣EurekaServer中的服務系統資料庫中将會存儲所有可用服務節點的資訊,服務節點的資訊可以在界面中直覺看到。
  • Eureka Client 通過注冊中心進行通路;它是一個Java用戶端,用于簡化Eureka Server的互動,用戶端同時也具備一個内置的使用輪詢負載算法的負載均衡器。在應用啟動後,将會向Eureka Server發送心跳預設周期為30秒。如果Eureka Server在多個心跳周期内沒有接收到某個節點的心跳,Eureka Server将會從服務系統資料庫中把這個服務節點移除,預設90秒。
    • Service Provider:服務提供方,将自身服務注冊到Eureka,進而使服務消費方能夠找到;
    • Service Consumer:服務消費方,從Eureka擷取注冊服務清單,進而能夠消費服務;

Eureka的自我保護機制:

預設情況下,如果Eureka Server在一定時間内(預設90秒)沒有接收到某個微服務執行個體的心跳,Eureka Server将會移除該執行個體。但是當網絡分區故障發生時,微服務與Eureka Server之間無法正常通信,而微服務本身是正常運作的,此時不應該移除這個微服務,是以引入了自我保護機制。

自我保護模式正是一種針對網絡異常波動的安全保護措施,使用自我保護模式能使Eureka叢集更加的健壯、穩定的運作。

如果在15分鐘内超過85%的用戶端節點都沒有正常的心跳,那麼Eureka就認為用戶端與注冊中心出現了網絡故障,Eureka Server自動進入自我保護機制:

  • Eureka Server不再從注冊清單中移除因為長時間沒收到心跳而應該過期的服務;
  • Eureka Server仍然能夠接受新服務的注冊和查詢請求,但是不會被同步到其它節點上,保證目前節點依然可用;
  • 當網絡穩定時,目前Eureka Server新的注冊資訊會被同步到其它節點中;

簡而言之,某時刻某一個微服務不可用了,Eureka不會立刻清理,依舊會對該微服務的資訊進行儲存。是以Eureka屬于AP。

服務熔斷降級

由于分布式架構中應用程式依賴關系可能非常多,每個依賴關系在某些時候将不可避免地失敗,針對服務調用失敗,為了縮小調用失敗的影響,引入了服務熔斷降級的思想。

多個微服務之間調用的時候,假設微服務A調用微服務B和微服務C,微服務B和微服務C又調用其它的微服務,這就是所謂的“扇出”。如果扇出的鍊路上某個微服務的調用響應時間過長或者不可用,對微服務A的調用就會占用越來越多的系統資源,進而引起系統崩潰,所謂的“雪崩效應”.

  • 服務熔斷:熔斷機制是應對雪崩效應的一種微服務鍊路保護機制,當鍊路的某個微服務不可用或者響應時間太長時,将快速的傳回設定好的提示資訊。
  • 服務降級:服務降級一般是指在伺服器壓力劇增的時候,根據實際業務使用情況以及流量,對一些服務和頁面有政策的不處理或者用一種簡單的方式進行處理,進而釋放伺服器資源的資源以保證核心業務的正常高效運作。

服務熔斷是應對系統服務雪崩的一種保險措施,給出的一種特殊降級措施。而服務降級則是更加寬泛的概念,主要是對系統整體資源的合理配置設定以應對壓力。服務熔斷可看作特殊降級。

Hystrix

Hystrix是一個用于處理分布式系統的延遲和容錯的開源庫,在分布式系統裡,許多依賴不可避免的會調用失敗,比如逾時、異常等,Hystrix能夠保證在一個依賴出問題的情況下,不會導緻整體服務失敗,避免級聯故障,以提高分布式系統的彈性。

"斷路器”本身是一種開關裝置,當某個服務單元發生故障之後,通過斷路器的故障監控(類似熔斷保險絲),向調用方傳回一個符合預期的、可處理的備選響應(FallBack),而不是長時間的等待或者抛出調用方無法處理的異常,這樣就保證了服務調用方的線程不會被長時間、不必要地占用,進而避免了故障在分布式系統中的蔓延,乃至雪崩。

"斷路器"思想:https://martinfowler.com/bliki/CircuitBreaker.html

分布式微服務治理
  • 熔斷打開:請求不再進行調用目前服務,内部定時一般為MTTR(平均故障處理時間),當打開時長達到所設的時長則進入半熔斷狀态;
  • 熔斷半開:部分請求根據規則調用目前服務,如果請求成功且符合規則則認為目前服務恢複正常,關閉熔斷;
  • 熔斷關閉:熔斷關閉不會對服務進行熔斷;

Hystrix工作流程:

分布式微服務治理
  1. 建立

    HystrixCommand

    HystrixObserableCommand

    對象。
  2. 指令執行:
    • 其中

      HystrixCommand

      實作了下面前兩種執行方式:
      • execute

        :同步執行,從依賴的服務傳回一個單一的結果對象或是在發生錯誤的時候抛出異常。
      • queue

        :異步執行,直接傳回一個Future對象,其中包含了服務執行結束時要傳回的單一結果對象。
    • HystrixObservableCommand

      實作了後兩種執行方式:
      • obseve()

        :傳回Observable對象,它代表了操作的多個結果,它是一個Hot Observable,不論“事件源”是否有“訂閱者”,都會在建立後對事件進行釋出,是以對于Hot Observable的每一個“訂閱者”都有可能是從“事件源”的中途開始的,并可能隻是看到了整個操作的局部過程。
      • toObservable()

        :同樣會傳回Observable對象,也代表了操作的多個結果,但它傳回的是一個Cold Observable,沒有“訂間者”的時候并不會釋出事件,而是進行等待,直到有“訂閱者"之後才釋出事件,是以對于Cold Observable 的訂閱者,它可以保證從一開始看到整個操作的全部過程。
  3. 判斷目前指令的請求緩存功能是被啟用的,并且該指令緩存命中,那麼緩存的結果會立即以Observable對象的形式傳回。
  4. 檢查斷路器是否為打開狀态。如果斷路器是打開的,那麼Hystrix不會執行指令,而是轉接到fallback處理邏輯(第8步);如果斷路器是關閉的,檢查是否有可用資源來執行指令(第5步)。
  5. 判斷線程池/請求隊列信号量是否占滿。如果指令依賴服務的專有線程地和請求隊列,或者信号量已經被占滿,那麼Hystrix也不會執行指令,而是轉接到fallback處理理輯(第8步) 。
  6. Hystrix會根據我們編寫的方法來決定采取什麼樣的方式去請求依賴服務:
    • HystrixCommand.run()

      :傳回一個單一的結果,或者抛出異常。
    • HystrixObservableCommand.construct()

      :傳回一個Observable對象來發射多個結果,或通過onError發送錯誤通知。
  7. Hystrix會将“成功”、“失敗”、“拒絕”、“逾時” 等資訊報告給斷路器,而斷路器會維護一組計數器來統計這些資料。斷路器會使用這些統計資料來決定是否要将斷路器打開,來對某個依賴服務的請求進行"熔斷/短路"。
  8. 當指令執行失敗的時候,Hystrix會進入fallback嘗試回退處理,我們通常也稱波操作為“服務降級”。而能夠引起服務降級處理的情況有下面幾種:
    • 第4步∶目前指令處于“熔斷/短路”狀态,斷路器是打開的時候。
    • 第5步∶目前指令的線程池、請求隊列或者信号量被占滿的時候。
    • 第6步∶

      HystrixObsevableCommand.construct()

      HytrixCommand.run()

      抛出異常的時候。
  9. 當Hystrix指令執行成功之後,它會将處理結果直接傳回或是以Observable的形式傳回給調用方。

服務網關

參考文章:

  • https://blog.csdn.net/rain_web/article/details/102469745
  • https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway
分布式微服務治理

網關的角色是作為一個 API 架構,用來保護、增強和控制對于 API 服務的通路。API 網關是一個處于應用程式或服務(提供 REST API 接口服務)之前的系統,用來管理授權、通路控制和流量限制等,這樣 REST API 接口服務就被 API 網關保護起來,對所有的調用者透明。是以,隐藏在 API 網關後面的業務系統就可以專注于建立和管理服務,而不用去處理這些政策性的基礎設施。

網關作用:

  • 作為所有API接口服務的請求接入點;
  • 作為所有後端業務服務的聚合點;
  • 實作安全、驗證、路由、過濾、流量等政策;
  • 對所有API服務和政策進行統一管理;

GetWay

Spring Cloud Gateway是Spring官方基于Spring 5.0,Spring Boot 2.0和Project Reactor等技術開發的網關,Spring Cloud Gateway旨在為微服務架構提供一種簡單而有效的統一的API路由管理方式。Spring Cloud Gateway作為Spring Cloud生态系中的網關,目标是替代ZUUL,其不僅提供統一的路由方式,并且基于Filter鍊的方式提供了網關基本的功能,例如:安全,監控/埋點,和限流等。

核心元件:

  • Route - 路由是建構網關的基本子產品,它由ID,目标URI,一系列的斷言和過濾器組成,如斷言為true則比對該路由;
  • Predicate - 斷言參考的是Java8的

    java.util.function.Predicate

    ,開發人員可以比對HTTP請求中的所有内容,例如請求頭或請求參數,如果請求與斷言相比對則進行路由;
  • Filter - 過濾指的是Spring架構中GatewayFilter的執行個體,使用過濾器,可以在請求被路由前或者之後對請求進行修改;

工作流程:

分布式微服務治理

用戶端向Spring Cloud Gateway送出請求。然後在Gateway Handler Mapping 中找到與請求相比對的路由,将其發送到GatewayWeb Handler,Handler再通過指定的過濾器鍊來将請求發送到我們實際的服務執行業務邏輯,然後傳回。

過濾器分為前置過濾器和後置過濾器,可以在發送代理請求之前或之後執行業務邏輯。

  • 前置過濾器可以做參數校驗、權限校驗、流量監控、日志輸出、協定轉換等;
  • 後置過濾器可以做響應内容、響應頭的修改,日志的輸出,流量監控等。

服務調用

參考文章:

  • https://www.jianshu.com/p/a6ad30738140
  • https://github.com/OpenFeign/feign
  • https://blog.csdn.net/qq_34978129/article/details/111183323
  • https://cloud.spring.io/spring-cloud-static

服務調用可以說是微服務中最關鍵的,如果沒有服務調用不會出現熔斷降級、也不會出現服務負載、服務注冊,分布式的服務治理可以說是圍繞服務調用展開的。

常見的服務之間的調用方式有兩種:

  • RPC遠端過程調用:定義資料式,基于原生TCP通信,速度快,效率高。早期的wedservice,現在熱門的dubbo,都是RPC的典型代表;
  • http調用:http其實是一種網絡傳輸協定,基于TCP,規定了資料傳輸的格式。現在用戶端浏覽器與伺服器端通信基本都是采用HTTP協定,也可以用來進行遠端服務調用。缺點是消息封裝臃腫,優勢是對服務的提供和調用方沒有任何技術限定,自由靈活,更符合為服務理念;

現在熱門的Rest風格,就可以通過HTTP協定來實作,如果公司全部采用Java技術棧,那麼使用Dubbo作為微服務架構是一個不錯的選擇;如果公司的技術棧多樣化,而且你更青睐Spring家族,那麼SpringCloud搭建微服務是不二之選。

OpenFeign

Feign is a declarative web service client. It makes writing web service clients easier. To use Feign create an interface and annotate it. It has pluggable annotation support including Feign annotations and JAX-RS annotations. Feign also supports pluggable encoders and decoders. Spring Cloud adds support for Spring MVC annotations and for using the same HttpMessageConverters used by default in Spring Web. Spring Cloud integrates Ribbon and Eureka, as well as Spring Cloud LoadBalancer to provide a load-balanced http client when using Feign.

大意:Feign是一個聲明式WebService用戶端。使用Feign能讓編寫Web Service用戶端更加簡單。它的使用方法是定義一個服務接口然後在上面添加注解。Feign也支援可拔插式的編碼器和解碼器。Spring Cloud對Feign進行了封裝,使其支援了Spring MVC标準注解和HttpMessageConverters。Feign可以與Eureka和Ribbon組合使用以支援負載均衡。

Feign和OpenFeign:

  • Feign是Spring Cloud元件中的一個輕量級RESTful的HTTP服務用戶端Feign内置了Ribbon,用來做用戶端負載均衡,去調用服務注冊中心的服務。Feign的使用方式是:使用Feign的注解定義接口,調用這個接口,就可以調用服務注冊中心的服務;
  • OpenFeign是Spring Cloud在Feign的基礎上支援了SpringMVC的注解,如@RequesMapping等等。OpenFeign的@Feignclient可以解析SpringMVc的@RequestMapping注解下的接口,并通過動态代理的方式産生實作類,實作類中做負載均衡并調用其他服務;

通過使用

OpenFeign

可以使代碼變得更加簡潔,減輕程式員負擔:

// 僞代碼
 @Component
 // 括号中,為在注冊中心注冊的服務名稱
 @FeignClient("CLOUD-PAYMENT-SERVICE")
 public interface PaymentFeignService {
 
     @GetMapping("/payment/get/{id}")
     CommonResult<Payment> getPayment(@PathVariable("id") Long id);
 
     @PostMapping("/payment/timeout")
     String feignTimeoutTest();
 }
           

openFeign工作原理:

分布式微服務治理
  1. 使用注解

    @FeignClient

    注冊

    FactoryBean

    到IOC容器, 最終産生了一個虛假的實作類代理;
  2. 使用Feign調用接口的地方,最終拿到的都是一個假的代理實作類;
  3. 所有發生在代理實作類上的調用,都被轉交給Feign架構,翻譯成HTTP的形式發送出去,并得到傳回結果,再翻譯回接口定義的傳回值形式;

服務負載

負載均衡,英文名稱為Load Balance,其含義就是指将工作任務進行平衡、分攤到多個操作單元上進行運作,例如FTP伺服器、Web伺服器、企業核心應用伺服器和其它主要任務伺服器等,進而協同完成工作任務。

目前服務與服務之間進行互相調用時,在分布式架構下應用都是叢集部署,是以這個時候就需要進行服務負載,即将收到的請求分攤到對應的伺服器上,進而達到系統的高可用。

常見負載均衡算法:

  • 随機配置設定:随機選擇一台伺服器來配置設定任務。它保證了請求的分散性達到了均衡的目的。同時它是沒有狀态的不需要維持上次的選擇狀态和均衡因子。但是随着任務量的增大,它的效果趨向輪詢後也會具有輪詢算法的部分缺點;
  • 輪詢配置設定:将任務配置設定給此時具有最小連接配接數的節點,是以它是動态負載均衡算法。一個節點收到一個任務後連接配接數就會加1,當節點故障時就将節點權值設定為0,不再給節點配置設定任務;
  • 最小連接配接配置設定:将任務配置設定給此時具有最小連接配接數的節點,是以它是動态負載均衡算法。一個節點收到一個任務後連接配接數就會加1,當節點故障時就将節點權值設定為0,不再給節點配置設定任務;
  • hash配置設定:對請求中的關鍵資訊進行hash計算,hash值相同的請求配置設定到同一台伺服器,具體原理可檢視HashMap配置設定原理;
  • 根據性能配置設定:根據伺服器的響應時間來進行任務配置設定,優先将新任務配置設定給響應最快的伺服器;

Ribbon

Spring Cloud Ribbon是基于Netflix Ribbon實作的一套用戶端負載均衡的工具,是一個内置軟體負載平衡器的程序間通信(遠端過程調用)庫。主要功能是提供用戶端的軟體負載均衡算法和服務調用。Ribbon用戶端元件提供一系列完善的配置項,如連接配接逾時、重試等。

本地負載與服務端負載:

  • Nginx是伺服器負載均衡,用戶端所有請求都會交給nginx,然後由nginx實作轉發請求。即負載均衡是由服務端實作的;
  • Ribbon是本地負載均衡,在調用微服務接口時候,會在注冊中心上擷取注冊資訊服務清單之後緩存到JVM本地,進而在本地實作RPC遠端服務調用技術;

Ribbon其實是一個軟負載均衡的用戶端元件,它可以和其他所需請求的用戶端結合使用,例如與Eureka結合:

分布式微服務治理

消費方和服務方在注冊中心注冊服務,當消費方發起請求時,Ribbon會去注冊中心尋找請求的服務名,即服務方叢集,Ribbon預設負載算法會根據

接口第幾次請求 % 伺服器叢集總數量

算出實際消費方伺服器的位置,每次服務重新開機動後rest接口計數從1開始。

模拟Ribbon預設負載均衡算法:

public interface ILoadBalance {
    ServiceInstance instance(List<ServiceInstance> instances); 
}
           
@Component
public class MyLoadBalance implements ILoadBalance{

    /**
     * 輪詢索引
     */
    private final AtomicInteger index = new AtomicInteger(0);

    /**
     * 負載均衡算法:rest接口第幾次請求數 % 伺服器叢集總數量 = 實際調用伺服器位置下标,每次服務重新開機動後rest接口計數從1開始。
     * @param instances 伺服器叢集數量
     * @return 實際伺服器的下标
     */
    @Override
    public ServiceInstance instance(List<ServiceInstance> instances) {
        return instances.get(incrementAndGet() % instances.size());
    }

    public final int incrementAndGet() {
        int current = 0;
        int next = 0;
        do {
            current = index.get();
            // 當最大數量超過 Integer.MAX_VALUE 歸0
            next = current >= 2147483647 ? 0 : current + 1;
        }while (!index.compareAndSet(current,next));
        return next;
    }
}
           
@Resource
 private RestTemplate restTemplate;

 @Resource
 private DiscoveryClient discoveryClient;

 @Resource
 private ILoadBalance iLoadBalance;

 @GetMapping("/myLoadBalance")
 public String myLoadBalanceTest() {

     List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
     ServiceInstance instance = iLoadBalance.instance(instances);

     URI uri = instance.getUri();
     String finalUri = String.format("%s/%s", uri, PaymentConstant.PAYMENT_GETPORT_API);

     log.info("自定義負載均衡,請求位址:{}", finalUri);

     return restTemplate.getForObject(finalUri, String.class);
 }
           

服務配置中心

在分布式微服務意味着要将單體應用中的業務拆分成一個個子服務,每個服務的粒度相對較小,是以系統中會出現大量的服務。由于每個服務都需要必要的配置資訊才能運作,是以一套集中式的、動态的配置管理設施是必不可少的。

配置中心應運而生。配置中心,顧名思義,就是來統一管理項目中所有配置的系統。對于單機版,我們稱之為配置檔案;對于分布式叢集系統,我們稱之為配置中心。

配置中心作用:

  • 統一管理不同環境、不同叢集的配置;
  • 将配置與應用分離、解耦合;
  • 版本釋出管理;

SpringCloud Config

參考文章:

  • https://www.springcloud.cc/spring-cloud-config.html
  • https://cloud.spring.io/spring-cloud-static/spring-cloud-config

SpringCloud Config為微服務架構中的微服務提供集中化的外部配置支援,配置伺服器為各個不同微服務應用的所有環境提供了一個中心化的外部配置。

分布式微服務治理

SpringCloud Config

是配置中心的一種,它分為服務端和用戶端兩部分:

  • 服務端也稱為分布式配置中心,它是一個獨立的微服務應用,用來連接配接配置伺服器并為用戶端提供擷取配置資訊,加密/解密資訊等通路接口;Config-Server端集中式存儲/管理配置檔案,并對外提供接口友善Config-Client通路,接口使用HTTP的方式對外提供通路;
  • 用戶端則是通過指定的配置中心來管理應用資源,以及與業務相關的配置内容,并在啟動的時候從配置中心擷取和加載配置資訊配置伺服器預設采用git來存儲配置資訊,這樣就有助于對環境配置進行版本管理,并且可以通過git用戶端工具來友善的管理和通路配置内容;

使用

SpringCloud Config

非常簡單,需要在服務端和用戶端分别進行改造:

  1. 引入依賴就不說了,首先将分布式中系統中的配置放到git或svn上,在服務端配置檔案裡配置好git或svn使用者名密碼、配置檔案所在的分支及配置檔案的目錄,再将服務端啟動類加上

    @EnableConfigServer

    注解,就大功告成了;
  2. 放在git或svn上的配置檔案名稱要符合規則,才能通過配置中心通路得到該檔案。一些常用的配置檔案規則,其中,label:分支、profiles:環境(dev/test/prod)、application:服務名:
    ## http://127.0.0.1:3344/master/config-dev.yml
     1. /{label}/{application}-{profile}.yml
    
     ## http://127.0.0.1:3344/config-dev.yml
     2. /{application}-{profile}.yml
    
     ## http://127.0.0.1:3344/config/dev/master
     3. /{application}/{profile}[/{label}]
               
  3. 在用戶端也要引入依賴和進行相關配置:配置中心位址、分支名稱、配置檔案名稱、環境,需要注意的是要将用戶端子產品下的

    application.yml

    檔案改為

    bootstrap.yml

    ,再将主啟動類加上

    @EnableEurekaClient

    注解;

    當配置用戶端啟動時,它綁定到配置伺服器(通過spring.cloud.config.uri引導配置屬性),并使用遠端屬性源初始化Spring Environment。

    這種行為的最終結果是,所有想要使用Config Server的用戶端應用程式都需要bootstrap.yml或一個環境變量

    applicaiton.yml是使用者級的資源配置項,而bootstrap.yml是系統級的,優先級更加高,在加載配置時優先加載bootstrap.yml

當将

SpringCloud Config

用戶端服務端都配置好之後,修改配置時會發現修改的配置檔案不能實時生效;針對這個問題,可以将服務重新開機或者調用

actuator

的重新整理接口使其生效,使用之前需要引入

actuator

的依賴:

# 使用SpringCloud Config修改完配置後,調用重新整理接口使用戶端配置生效
 curl -X POST "http://localhost:3355/actuator/refresh"
           

為了避免手動的調用重新整理接口,可以使用

SpringCloud Bus

配合

SpringCloud Config

實作配置的動态重新整理。

服務開發

長期以來 Java 的開發一直讓人所诟病:項目開發複雜度極其高、項目的維護非常困難;即便使用了大量的開發架構,發現我們的開發也沒少多少。為了解決讓開發更佳簡單,項目更容易管理,SpringBoot誕生了。

Spring Boot是一個廣泛用來建構Java微服務的架構,它基于Spring依賴注入架構來進行工作。

SpringBoot

官網位址:https://spring.io/projects/spring-boot

SpringBoot

是由

Pivotal

團隊提供的全新架構,其設計目的是用來簡化新

Spring

應用的初始搭建以及開發過程。

該架構使用了特定的方式來進行配置,進而使開發人員不再需要定義樣闆化的配置。

SpringBoot

提供了一種新的程式設計範式,可以更加快速便捷地開發

Spring

項目,在開發過程當中可以專注于應用程式本身的功能開發,而無需在

Spring

配置上花太大的工夫。

SpringBoot

基于

Sring4

進行設計,繼承了原有

Spring

架構的優秀基因。

SpringBoot

準确的說并不是一個架構,而是一些類庫的集合。

maven

或者

gradle

項目導入相應依賴即可使用

SpringBoot

,而無需自行管理這些類庫的版本。

特點:

  • 獨立運作的

    Spring

    項目:

    SpringBoot

    可以以 jar 包的形式獨立運作,運作一個

    SpringBoot

    項目隻需通過

    java–jar xx.jar

    來運作。
  • 内嵌

    Servlet

    容器:

    SpringBoot

    可選擇内嵌

    Tomcat

    Jetty

    或者

    Undertow

    ,這樣我們無須以

    war

    包形式部署項目。
  • 提供

    starter

    簡化

    Maven

    配置:

    Spring

    提供了一系列的

    starter

    pom 來簡化

    Maven

    的依賴加載,例如,當你使用了

    spring-boot-starter-web

    時,會自動加入依賴包。
  • 自動配置

    Spring

    SpringBoot

    會根據在類路徑中的 jar 包、類,為 jar 包裡的類自動配置 Bean,這樣會極大地減少我們要使用的配置。當然,

    SpringBoot

    隻是考慮了大多數的開發場景,并不是所有的場景,若在實際開發中我們需要自動配置

    Bean

    ,而

    SpringBoot

    沒有提供支援,則可以自定義自動配置。
  • 準生産的應用監控:

    SpringBoot

    提供基于

    http、ssh、telnet

    對運作時的項目進行監控。
  • 無代碼生成和 xml 配置:

    SpringBoot

    的神奇的不是借助于代碼生成來實作的,而是通過條件注解來實作的,這是

    Spring 4.x

    提供的新特性。

    Spring 4.x

    提倡使用 Java 配置和注解配置組合,而

    SpringBoot

    不需要任何 xml 配置即可實作

    Spring

    的所有配置。