導讀

網(wǎng)站建設哪家好,找創(chuàng)新互聯(lián)公司!專注于網(wǎng)頁設計、網(wǎng)站建設、微信開發(fā)、小程序制作、集團企業(yè)網(wǎng)站建設等服務項目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了恒山免費建站歡迎大家使用!
一段時期以來 “微服務架構 ”一直是一個熱門詞匯,各種技術類公眾號或架構分享會議上,關于微服務架構的討論和主題也都非常多。對于大部分初創(chuàng)互聯(lián)網(wǎng)公司來說,早期的單體應用結構才是最合適的選擇,只有當業(yè)務進入快速發(fā)展期,在系統(tǒng)壓力、業(yè)務復雜度以及人員擴展速度都快速上升的情況下,如何快速、穩(wěn)妥有序的將整個互聯(lián)網(wǎng)軟件系統(tǒng)升級成微服務架構,以滿足業(yè)務發(fā)展需要及技術組織的重新塑造,才是進行微服務架構的最主要的動力,否則空談微服務架構是沒有意義的。
而一旦決定將整個應用體系按照微服務架構體系進行升級,就需要有組織有計劃的進行業(yè)務系統(tǒng)、基礎架構、運維體系等多個方面的升級配套。而另一個比較尷尬的現(xiàn)實是,一般業(yè)務發(fā)展進入到需要進行微服務架構層面的時候,業(yè)務發(fā)展往往又都是非常迅猛的,這種業(yè)務快速發(fā)展和增長的壓力往往又會給整個技術團隊帶來非常大的挑戰(zhàn),因為此時你需要取舍,是簡單方案快速支撐呢?還是選擇適當長遠一點的方案?當然這種情況大部分是技術細節(jié)方面的問題,掌控的“度”大部分情況是掌握在具體的工程師手中。
而如何整體上確保應用體系及組織結構向微服務時代快速、有序的跨越,是一件十分考驗團隊能力以及架構管理水平的事。能做到80分已然算優(yōu)秀了,因為這是有其客觀規(guī)律的!
作者自身親歷了一個快速發(fā)展的互聯(lián)網(wǎng)公司從單體應用~以Spring Cloud為技術棧的微服務架構體系的全過程。本文將主要從技術角度與大家探討如何利用Spring Cloud進行微服務架構拆分,以及在這個過程中一點自己的思考。水平有限,不足之處還請包涵!
系統(tǒng)架構演變概述

在公司業(yè)務初創(chuàng)時期,面對的主要問題是如何將一個想法變成實際的軟件實現(xiàn),在這個時候整個軟件系統(tǒng)的架構并沒有搞得那么復雜,為了快速迭代,整個軟件系統(tǒng)就是由“App+后臺服務”組成,而后臺服務也只是從工程角度將應用進行Jar包的拆分。此時軟件系統(tǒng)架構如下:

而此時整個軟件系統(tǒng)的功能也比較簡單,只有基本的用戶、訂單、支付等功能,并且由于業(yè)務流程沒有那么復雜,這些功能基本耦合在一起。而隨著App的受歡迎程度(作者所在的公司正好處于互聯(lián)網(wǎng)熱點),所以App下載量在2017年迅猛增長,在線注冊人數(shù)此時也是蹭蹭往上漲。
隨著流量的迅猛增長,此時整個后臺服務的壓力變得非常大,為了抗住壓力只能不斷的加機器,平行擴展后臺服務節(jié)點。此時的部署架構如下:

通過這種方式,整個軟件系統(tǒng)抗住了一波壓力,然而系統(tǒng)往往還是會偶爾出點事故,特別是因為API中的某個接口性能問題導致整個服務不可用,因為這些接口都在一個JVM進程中,雖然此時部署了多個節(jié)點,但因為底層數(shù)據(jù)庫、緩存系統(tǒng)都是一套,所以還是會出現(xiàn)一掛全掛的情況。
另一方面,隨著業(yè)務的快速發(fā)展,以往相對簡單的功能變得復雜起來,這些功能除了有用戶看得見的、也會包括很多用戶看不見的,就好像百度搜索,用戶能看見的可能只是一個搜索框,但是實際上后臺對應的服務可能是成百上千,如有些增長策略相關的功能:紅包、分享拉新等。還有些如廣告推薦相關的變現(xiàn)功能等。
此外,流量/業(yè)務的增長也意味著團隊人數(shù)的迅速增長,如果此時大家開發(fā)各自的業(yè)務功能還是用一套服務代碼,很難想象百十來號人,在同一個工程在疊加功能會是一個什么樣的場景。所以如何劃分業(yè)務邊界、合理的進行團隊配置也是一件十分迫切的事情了!
為了解決上述問題,適應業(yè)務、團隊發(fā)展,架構團隊決定進行微服務拆分。而要實施微服務架構,除了需要合理的劃分業(yè)務模塊邊界外,也需要一整套完整的技術解決方案。
在技術方案的選擇上,服務拆分治理的框架也是有很多,早期的有如WebService,近期的則有各種Rpc框架(如Dubbo、Thirft、Grpc)。而Spring Cloud則是基于Spring Boot提供的一整套微服務解決方案,因為技術棧比較新,并且各類組件的支撐也非常全面,所以Spring Cloud就成為了首選。
經(jīng)過一系列的重構+擴展,整個系統(tǒng)架構最終形成了以APP為中心的一套微服務軟件系統(tǒng),結構如下:

到這里,整個軟件系統(tǒng)就基于Spring Cloud初步完成了微服務體系的拆分。支付、訂單、用戶、廣告等核心功能抽離成獨立的微服務,與此同時各自微服務對應的數(shù)據(jù)庫也按照服務邊界進行了拆分。
在完成服務的拆分以后,原來功能邏輯之間的代碼調用關系,轉換成了服務間網(wǎng)絡的調用關系,而各個微服務需要根據(jù)各自所承載的功能提供相應的服務,此時服務如何被其他服務發(fā)現(xiàn)并調用,就成了整個微服務體系中比較關鍵的部分,使用過Dubbo框架的同學知道,在Dubbo中服務的注冊&發(fā)現(xiàn)是依賴于ZooKeeper實現(xiàn)的,而在Spring Cloud中我們是通過Consul來實現(xiàn)。另外在基于Spring Cloud的架構體系中,提供了配置中心(ConfigServer)來幫助各個微服務管理配置文件,而原本的API服務,隨著各個功能的抽離,逐步演變成前置網(wǎng)關服務了。
聊到這里,基于Spring Cloud我們進行了微服務拆分,而在這個體系結構中,分別提到了Consul、ConfigServer、網(wǎng)關服務這幾個關鍵組件,那么這幾個關鍵組件具體是如何支撐這個龐大的服務體系的呢?
Spring Cloud關鍵組件

Consul
Consul是一個開源的,使用Go語言開發(fā)的注冊中心服務。它里面內置了服務發(fā)現(xiàn)與注冊框架、分布一致性協(xié)議實現(xiàn)、健康檢查、Key/Value存儲、多數(shù)據(jù)中心等多個方案。在Spring Cloud框架中還可以選擇Eurke作為注冊中心,這里之所以選擇Consul主要原因在于Consul對異構的服務的支持,如:gRPC服務。
事實上,在后續(xù)的系統(tǒng)架構演進中,在某些服務模塊進一步向子系統(tǒng)化拆分的過程中,就采用了gRPC作為子系統(tǒng)服務間的調用方式。例如,支付模塊的繼續(xù)擴張,對支付服務本身又進行了微服務架構的拆分,此時支付微服務內部就采用了gRPC的方式進行調用,而服務注冊與發(fā)現(xiàn)本身則還是依賴于同一套Consul集群。
此時的系統(tǒng)架構演進如下:

原有微服務架構中的模塊服務在規(guī)模達到一定程度或復雜性達到一定程度后,都會朝著獨立的體系發(fā)展,從而將整個微服務的調用鏈路變的非常長,而從Consul的角度看,所有的服務又都是扁平的。
隨著微服務規(guī)模的越來越大,Consul作為整個體系的核心服務組件,在整個體系中處于關鍵的位置,一旦Consul掛掉,所有的服務都將停止服務。那么Consul到底是什么樣服務?其容災機制又該如何設計呢?
要保證Consul服務的高可用,在生產(chǎn)環(huán)境Consul應該是一個集群(關于Consul集群的安裝與配置可以參考網(wǎng)絡資料),這是毫無疑問的。而在Consul集群中,存在兩種角色:Server、Client,這兩種角色與Consul集群上運行的應用服務并沒有什么關系,只是基于Consul層面的一種角色劃分。實際上,維持整個Consul集群狀態(tài)信息的還是Server節(jié)點,與Dubbo中使用ZooKeeper實現(xiàn)注冊中心一樣,Consul集群中的各個Server節(jié)點也需要通過選舉的方式(使用GOSSIP協(xié)議、Raft一致性算法,這里不做詳細展開,在后面的文章中可以和大家單獨討論)來選舉整個集群中的Leader節(jié)點來負責處理所有查詢和事務,并向其他節(jié)點同步狀態(tài)信息。
而Client角色則是相對無狀態(tài)的,只是簡單的代理轉發(fā)RPC請求到Server節(jié)點,之所以存在Client節(jié)點主要是分擔Server節(jié)點的壓力,作一層緩沖而已,這主要是因為Server節(jié)點的數(shù)量不宜過多,因為Server節(jié)點越多也就意味著達成共識的過程越慢,節(jié)點間同步的代價也就越高。對于Server節(jié)點,一般建議3-5臺,而Client節(jié)點則沒有數(shù)量的限制,可以根據(jù)實際情況部署數(shù)千或數(shù)萬臺。事實上,這也只是一種策略,在現(xiàn)實的生產(chǎn)環(huán)境中,大部分應用只需要設置3~5臺Server節(jié)點就夠了,作者所在的公司一套生產(chǎn)集群中的Consul集群的節(jié)點配置就是5個Server節(jié)點,并沒有額外再設置Client節(jié)點。
另外,在Consul集群中還有一個概念是Agent,事實上每個Server或Client都是一個consul agent,它是運行在Consul集群中每個成員上的一個守護進程,主要的作用是運行DNS或HTTP接口,并負責運行時檢查和保持服務信息同步。我們在啟動Consul集群的節(jié)點(Server或Client)時,都是通過Consul Agent的方式啟動的。例如:
consul agent -server -bootstrap -syslog \ -ui \ -data-dir=/opt/consul/data \ -dns-port=53 -recursor=10.211.55.3 -config-dir=/opt/consul/conf \ -pid-file=/opt/consul/run/consul.pid \ -client=10.211.55.4 \ -bind=10.211.55.4 \ -node=consul-server01 \ -disable-host-node-id &
以實際的生產(chǎn)環(huán)境為例,Consul集群的部署結構示意圖如下:

實際生產(chǎn)案例中并沒有設置Client節(jié)點,而是通過5個Consul Server節(jié)點組成的集群,來服務整套生產(chǎn)集群的應用注冊&發(fā)現(xiàn)。這里有細節(jié)需要了解下,實際上5個Consul Server節(jié)點的IP地址是不一樣的,具體的服務在連接Consul集群進行服務注冊與查詢時應該連接Leader節(jié)點的IP,而問題是,如果Leader節(jié)點掛掉了,相應的應用服務節(jié)點,此時如何連接通過Raft選舉產(chǎn)生的新Leader節(jié)點呢?難道手工切換IP不成?
顯然手工切換IP的方式并不靠譜,而在生產(chǎn)實踐中,Consul集群的各個節(jié)點實際上是在Consul Agent上運行DNS(如啟動參數(shù)中紅色字體部分),應用服務在連接Consul集群時的IP地址為DNS的IP,DNS會將地址解析映射到Leader節(jié)點對應的IP上,如果Leader節(jié)點掛掉,選舉產(chǎn)生的新Leader節(jié)點會將自己的IP通知DNS服務,DNS更新映射關系,這一過程對各應用服務則是透明的。
通過以上分析,Consul是通過集群設計、Raft選舉算法,Gossip協(xié)議等機制來確保Consul服務的穩(wěn)定與高可用的。如果需要更高的容災級別,也可以通過設計雙數(shù)據(jù)中心的方式,來異地搭建兩個Consul數(shù)據(jù)中心,組成一個異地災備Consul服務集群,只是這樣成本會更高,這就看具體是否真的需要了。
ConfigServer(配置中心)
配置中心是對微服務應用配置進行管理的服務,例如數(shù)據(jù)庫的配置、某些外部接口地址的配置等等。在Spring Cloud中ConfigServer是獨立的服務組件,它與Consul一樣也是整個微服務體系中比較關鍵的一個組件,所有的微服務應用都需要通過調用其服務,從而獲取應用所需的配置信息。
隨著微服務應用規(guī)模的擴大,整個ConfigServer節(jié)點的訪問壓力也會逐步增加,與此同時,各個微服務的各類配置也會越來越多,如何管理好這些配置文件以及它們的更新策略(確保不因生產(chǎn)配置隨意改動而造成線上故障風險),以及搭建高可用的ConfigServer集群,也是確保微服務體系穩(wěn)定很重要的一個方面。
在生產(chǎn)實踐中,因為像Consul、ConfigServer這樣的關鍵組件,需要搭建獨立的集群,并且部署在物理機而不是容器里。在上一節(jié)介紹Consul的時候,我們是獨立搭建了5個Consul Server節(jié)點。而ConfigServer因為主要是http配置文件訪問服務,不涉及節(jié)點選舉、一致性同步這樣的操作,所以還是按照傳統(tǒng)的方式搭建高可用配置中心。具體結構示意圖如下:

我們可以單獨通過Git來管理應用配置文件,正常來說由ConfigSeever直接通過網(wǎng)絡拉取Git倉庫的配置供服務獲取就可以了,這樣只要Git倉庫配置更新,配置中心就能立刻感知到。但是這樣做的不穩(wěn)定之處,就在于Git本身是內網(wǎng)開發(fā)用的代碼管理工具,如果讓線上實時服務直接讀取,很容易將Git倉庫拉掛了,所以,我們在實際的運維過程中,是通過Git進行配置文件的版本控制,區(qū)分線上分支/master與功能開發(fā)分支/feature,并且在完成mr后還需要手工(通過發(fā)布平臺觸發(fā))同步一遍配置,過程是將新的master分支的配置同步一份到各個ConfigServer節(jié)點所在主機的本地路徑,這樣ConfigServer服務節(jié)點就可以通過其本地目錄獲取配置文件,而不用多次調用網(wǎng)絡獲取配置文件了。
而另一方面,隨著微服務越來越多,Git倉庫中的配置文件數(shù)量也會越來越多。為了便于配置的管理,我們需要按照一定的組織方式來組織不同應用類型的配置。在早期所有的應用因為沒有分類,所以導致上百個微服務的配置文件放在一個倉庫目錄,這樣一來導致配置文件管理成本增加,另外一方面也會影響ConfigServer的性能,因為某個微服務用不到的配置也會被ConfigServer加載。
所以后期的實踐是,按照配置的層次關系進行組織,將公司全局的項目配置抽象到頂層,由ConfigServer默認加載,而其他所有的微服務則按照應用類型進行分組(通過Git項目空間的方式分組),相同的應用放在一個組,然后這個組下單獨設立一個名為Config的Git倉庫來存放這個組下相關微服務的配置文件。層次結構如下:

這樣應用加載配置的優(yōu)先級就是“本地配置->common配置->組公共配置->項目配置”這樣的順序。例如某服務A,在項目工程的默認配置文件(“bootstrap.yml/application.yml”)中配置了參數(shù)A,同時也在本地項目配置“application-production.yml”配置了參數(shù)B,而與此同時,ConfigServer中的common倉庫下的配置文件“application.yml/application-production.yml”又分別存在參數(shù)C、參數(shù)D,同時有個組叫“pay”,其下的默認配置文件“application.yml/application-production.yml”存在參數(shù)E、參數(shù)F,具體項目pay-api又存在配置文件“pay-api-production.yml”其覆蓋了common倉庫中參數(shù)C、參數(shù)D的值。那么此時如果該應用以“spring.profiles.active=production”的方式啟動,那么其能獲取到的配置參數(shù)(通過鏈接訪問:http://{spring.cloud.config.uri}/pay-api-production.yml)就是A、B、C、D、E、F,其中C、D的參數(shù)值為pay-api-production.yml中最后覆蓋的值。
而對于ConfigServer服務本身來說,需要按照這樣的組織方式進行配置類型匹配,例如上述的例子中,假設還存在finance的配置倉庫,而pay組下的服務訪問配置中心的時候,是不需要finance空間下的配置文件的,所以ConfigServer可以不用加載。這里就需要在ConfigServer服務配置中進行一些配置。具體如下:
spring: application: name: @project.artifactId@ version: @project.version@ build: @buildNumber@ branch: @scmBranch@ cloud: inetutils: ignoredInterfaces: - docker0 config: server: health.enabled: false git: uri: /opt/repos/config searchPaths: 'common,{application}' cloneOnStart: true repos: pay: pattern: pay-* cloneOnStart: true uri: /opt/repos/example/config searchPaths: 'common,{application}' finance: pattern: finance-* cloneOnStart: true uri: /opt/repos/finance/config searchPaths: 'common,{application}'
通過在ConfigServer服務本身的application.yml本地配置中,設置其配置搜索方式,來實現(xiàn)這樣的目的。
網(wǎng)關服務&服務熔斷&監(jiān)控
通過上面兩小節(jié)的內容,我們相對詳細地介紹了基于Spring Cloud體系中比較關鍵的兩個服務組件。然而在微服務架構體系中,還有很多關鍵的問題需要解決,例如,應用服務在Consul中部署了多個節(jié)點,那么調用方如何實現(xiàn)
負載均衡?
關于這個問題,在傳統(tǒng)的架構方案中是通過Nginx實現(xiàn)的,但是在前面介紹Consul的時候只提到了Consul的服務注冊&發(fā)現(xiàn)、選舉等機制,并沒有提到Consul如何在實現(xiàn)服務調用的負載均衡。難道基于Spring Cloud的微服務體系中的應用服務都是單節(jié)點在提供服務,哪怕即使部署了多個服務節(jié)點?事實上,我們在服務消費方通過@EnableFeignClients注解開啟調用,通過@FeignClient("user")注解進行服務調用時,就已經(jīng)實現(xiàn)了負載均衡,為什么呢?因為,這個注解默認是會默認開啟Robbin代理的,而Robbin是實現(xiàn)客戶端負載均衡的一個組件,通過從Consul拉取服務節(jié)點信息,從而以輪詢的方式轉發(fā)客戶端調用請求至不同的服務端節(jié)點來實現(xiàn)負載均衡。而這一切都是在消費端的進程內部通過代碼的方式實現(xiàn)的。這種負載方式寄宿于消費端應用服務上,對消費端存在一定的代碼侵入性,這是為什么后面會出現(xiàn)Service Mesh(服務網(wǎng)格)概念的原因之一,這里就不展開了,后面有機會再和大家交流。
另一需要解決的關鍵問題是服務熔斷、限流等機制的實現(xiàn),Spring Cloud通過集成Netflix的Hystrix框架來提供這種機制的支持,與負載均衡機制一樣也是在消費端實現(xiàn)。由于篇幅的關系,這里也不展開了,在后面的文章中有機會再和大家交流。
此外還有Zuul組件來實現(xiàn)API網(wǎng)關服務,提供路由分發(fā)與過濾相關的功能。而其他輔助組件還有諸如Sleuth來實現(xiàn)分布式鏈路追蹤、Bus實現(xiàn)消息總線、Dashboard實現(xiàn)監(jiān)控儀表盤等。由于Spring Cloud的開源社區(qū)比較活躍,還有很多新的組件在不斷的被集成進來,感興趣的朋友可以持續(xù)關注下!
微服務之運維形態(tài)

在微服務體系結構下,隨著服務數(shù)量大量的增長,線上的部署&維護的工作量會變得非常大,而如果還采用原有的運維模式的話,就能難滿足需要了。此時運維團隊需要實施DevOps策略,開發(fā)自動化運維發(fā)布平臺,打通產(chǎn)品、開發(fā)、測試、運維流程,關注研發(fā)效能。
另外一方面也需要推進容器化(Docker/Docker Swarm/Kubernetes)策略,這樣才能快速對服務節(jié)點進行伸縮,這也是微服務體系下的必然要求。
微服務泛濫問題

這里還需要注意一個問題,就是實施微服務架構后,如何在工程上管控微服務的問題。盲目的進行微服務的拆分也不是一件很合理的事情,因為這會導致整個服務調用鏈路變得深不可測,對問題排查造成難度,也浪費線上資源。
重構問題

在早期單體架構方式向微服務架構的轉變過程中,重構是一個非常好的方式,也是確保服務規(guī)范化,業(yè)務系統(tǒng)應用架構合理化的很重要的手段。但是,一般來說,在快速發(fā)展階段也就意味著團隊規(guī)模的迅速增長,短時間內如何讓新的團隊有事可做也是一件非常考驗管理水平的事情,因為如果招了很多人,并且他們之間呈現(xiàn)一種過渡的競爭狀態(tài)的話,就會出現(xiàn)讓重構這件事變得有些功利的情況,從而導致重構不徹底、避重就輕,導致表象上看是很高大上的微服務架構,而業(yè)務系統(tǒng)實際上比較爛的情況。
另外,重構是在一定階段后作出的重要決策,不僅僅是重新拆分,也是對業(yè)務系統(tǒng)的重新塑造,所以一定要考慮好應用軟件的系統(tǒng)結構以及實施它們所需要付出的成本,切不可盲目!
后記

基于Spring Cloud的微服務架構體系,通過集成各種開源組件來為整個體系服務支持,但是在負載均衡、熔斷、流量控制的方面需要對服務消費端的業(yè)務進程進行侵入。所以很多人會認為這不是一件很好的事情,于是出現(xiàn)了Service Mesh(服務網(wǎng)格)的概念,Service Mesh的基本思路就是通過主機獨立Proxy進行的部署來解耦業(yè)務系統(tǒng)進程,這個Proxy除了負責服務發(fā)現(xiàn)和負載均衡(不再需要單獨的注冊組件,如Consul)外,還負責動態(tài)路由、容錯限流、監(jiān)控度量和安全日志等功能。
而在具體的服務組件上目前主要是Google/IBM等大廠支持和推進的一個叫做Istio的Service Mesh標準化工作組。具體關于Service Mesh的知識,在后面的內容中再和大家交流。以上就是本文的全部內容,來波關注,后面分享更多干貨內容?。。?
名稱欄目:基于SpringCloud的微服務架構演變史
文章起源:http://chinadenli.net/article30/gicdso.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供建站公司、品牌網(wǎng)站建設、網(wǎng)站策劃、搜索引擎優(yōu)化、網(wǎng)站設計、標簽優(yōu)化
廣告
聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經(jīng)允許不得轉載,或轉載時需注明來源:
創(chuàng)新互聯(lián)