1 回答

TA貢獻2016條經(jīng)驗 獲得超9個贊
Spring Cloud項目的既定目標在于為Spring開發(fā)人員提供一整套易于使用的工具集,從而保證其輕松構(gòu)建起自己需要的分布式系統(tǒng)方案。為了實現(xiàn)這一目標,Spring Cloud以Netflix OSS堆棧為基礎將大量實現(xiàn)堆棧加以整合并打包。這些堆棧而后可以通過大家所熟知的各類基于注釋的配置工具、Java配置工具以及基于模板的編程工具實現(xiàn)交付。下面就讓我們一起了解Spring Cloud當中的幾類常見組件。
Spring Cloud Config Server
Spring Cloud Config Server能夠提供一項具備橫向擴展能力的集中式配置服務。它所使用的數(shù)據(jù)被保存在一套可插拔庫層當中,后者目前能夠支持本地存儲、Git以及Subversion。通過利用一套版本控制系統(tǒng)作為配置存儲方案,開發(fā)人員能夠輕松實現(xiàn)版本與審計配置的內(nèi)容調(diào)整。
配置內(nèi)容會以Java屬性或者YAML文件的形式體現(xiàn)。該Config Server會將這些文件合并為環(huán)境對象,其中包含易于理解的Spring屬性模型以及作為REST API存在的配置文件。任何應用程序都能夠直接調(diào)用該REST API當中所包含的配置數(shù)據(jù),但我們也可以將智能客戶端綁定方案添加到Spring Boot應用程序當中,并由后者自動將接收自Config Server的配置信息分配至任意本地配置當中。
Spring Cloud Bus
Spring Cloud Config Server是一套強大的配置分發(fā)機制,能夠在保障一致性的前提下將配置內(nèi)容分發(fā)到多個應用程序?qū)嵗斨小H欢鶕?jù)其設計思路的限定,我們目前只能在應用程序啟動時對其配置進行更新。在向Git中的某一屬性發(fā)送新值時,我們需要以手動方式重啟每個應用程序進程,從而保證該值被切實納入應用當中。很明顯,大家需要能夠在無需重啟的前提下完成對應用程序配置內(nèi)容的更新工作。
Spring Cloud Bus的任務正是為應用程序?qū)嵗砑右惶坠芾肀嘲濉K壳耙揽繉⒁惶卓蛻舳私壎ㄖ烈唤MAMQP交換與隊列當中來實現(xiàn),但這一后端在設計上也實現(xiàn)了可插拔特性。Spring Cloud Bus為我們的應用程序帶來了更多管理端點。在圖二中,我們可以看到一個面向greeting屬性的值被發(fā)送至Git當中,而后一條請求被發(fā)送至應用A中的/bus/refresh端點。該請求會觸發(fā)以下三個事件:
應用A從Config Server處請求獲取最新版本的配置內(nèi)容。任意注明了@RefreshScope的Spring Bean都會被重新初始化并載入新的配置內(nèi)容。
應用A向AMQP交換機制發(fā)送一條消息,表明其已經(jīng)收到更新指示。
通過監(jiān)聽AMQP隊列而被納入Cloud Bus的應用B與應用C會獲取到上述消息,并以與應用A同樣的方式實現(xiàn)配置更新。
現(xiàn)在我們已經(jīng)有能力在無需重啟的情況下對應用程序配置進行更新了。
Spring Cloud Netflix
Spring Cloud Netflix針對多種Netflix組件提供打包方案,其中包括Eureka、Ribbon、Hystrix以及Zuul。接下來我將分別對它們作出講解。
Eureka是一套彈性服務注冊實現(xiàn)方案。其中服務注冊屬于服務發(fā)現(xiàn)模式的一種實現(xiàn)機制
Spring Cloud Netflix通過直接將spring-cloud-starter-eureka-server關聯(lián)性添加到Spring Boot應用程序、隨后將該應用程序的配置類與@EnableEurekaServer相整合的方式病嵌入式Eureka服務器的部署工作。
應用程序能夠通過添加spring-cloud-starter-eureka關聯(lián)性并將其配置類與@EnableDiscoveryClient相整合的方式加入到服務發(fā)現(xiàn)流程當中。通過整合,我們能夠?qū)⒔?jīng)過配置的適合DiscoveryClient實例注入至任意Spring Bean內(nèi)。在我們所列舉的實例中,DiscoveryClient作為服務發(fā)現(xiàn)的一種抽象機制恰好可以通過Eureka實現(xiàn),不過大家也可以將其與Consul等其它備選堆棧相集成。DiscoveryClient能夠通過服務的邏輯標識符提供位置信息(例如網(wǎng)絡地址)以及其它與已注冊至Eureka的服務實例相關的元數(shù)據(jù)。
Eureka提供的負載均衡機制僅支持單循環(huán)條件。而Ribbon提供的客戶端IPC庫則更為精巧,其同時具備可配置負載均衡機制與故障容錯能力。Ribbon能夠通過獲取自Eureka服務器的動態(tài)服務器列表進行內(nèi)容填充。Spring Cloud Netflix通過將spring-cloud-starter-ribbon關聯(lián)性添加至Spring Boot應用程序的方式實現(xiàn)與Ribbon的集成。這套額外庫允許用戶將經(jīng)過適當配置的LoadBalancerClient實例注入至Spring Bean當中,從而實現(xiàn)客戶端負載均衡(如圖四所示)。
在此類任務當中,我們可以利用Ribbon實現(xiàn)額外負載均衡算法,包括可用性過濾、加權響應時間以及可用域親和等。
Spring Cloud Netflix還通過自動創(chuàng)建能夠被注入至任意Spring Bean的Ribbon強化型RestTemplate實例的方式進一步改進了Spring開發(fā)者的Ribbon使用方式。在此之后,開發(fā)人員能夠輕松將URL所提供的邏輯服務名稱遞交至RestTemplate:
@Autowired @LoadBalanced private RestTemplate restTemplate; @RequestMapping("/") public String consume() { ProducerResponse response = restTemplate.getForObject("http://producer", ProducerResponse.class); return String.format("{\"value\": %s}", response.getValue()); }
Hystrix能夠為斷路器以及密閉閘門等分布式系統(tǒng)提供一套通用型故障容錯實現(xiàn)模式。斷路器通常會被作為一臺狀態(tài)機使用,具體如圖五所示。
斷路器能夠介于服務及其遠程關聯(lián)性之間。如果該電路處于閉合狀態(tài),則所有指向該關聯(lián)性的調(diào)用通常將直接通過。如果某一調(diào)用失敗,則故障將被計入計數(shù)。而一旦失敗次數(shù)達到可配置時間區(qū)間內(nèi)的閾值,該電路將被跳閘至斷開。在處于斷開狀態(tài)時,調(diào)用將不再被發(fā)往該關聯(lián),而由此產(chǎn)生的結(jié)果將可自行定制(包括報告異常、返回虛假數(shù)據(jù)或者調(diào)用其它關聯(lián)等等)。
該狀態(tài)機會定期進入所謂“半開”狀態(tài),旨在檢測關聯(lián)性是否處于健康運作狀態(tài)。在這種狀態(tài)下,請求一般仍將繼續(xù)得以通過。當請求成功通過時,該設備會重新回歸閉合狀態(tài)。而如果請求失敗,則該設備會重新回歸斷開狀態(tài)。
Spring Cloud應用程序能夠通過添加spring-cloud-starter-hystrix關聯(lián)性并將其配置類與@EnableCircuitBreaker相整合的方式利用Hystrix。在此之后,大家可以通過與@HystrixCommand整合的方式將斷路器機制納入到任意Spring Bean方法內(nèi):
@HystrixCommand(fallbackMethod = "getProducerFallback") public ProducerResponse getValue() { return restTemplate.getForObject("http://producer", ProducerResponse.class); } 以上實例中指定了一個名為getProducerFallback的備用方法。當該斷路器處于斷開狀態(tài)時,此方法將替代getValue接受調(diào)用: private ProducerResponse getProducerFallback() { return new ProducerResponse(42); }
除了實現(xiàn)狀態(tài)機機制之外,Hystrix還能夠提供來自各斷路機制的重要遙測指標流,具體包括請求計量、響應時間直方圖以及成功、失敗與短路請求數(shù)量等(如圖六所示)。
Zuul能夠處理全部指向Netflix邊緣服務的輸入請求。它能夠與Ribbon以及Hystrix等其它Netflix組件相結(jié)合,從而提供一個靈活且具有彈性的Netflix服務路由層。
Netflix公司在Zuul當中加載動態(tài)過濾機制,從而實現(xiàn)以下各項功能:
驗證與安全保障: 識別面向各類資源的驗證要求并拒絕那些與要求不符的請求。
審查與監(jiān)控: 在邊緣位置追蹤有意義數(shù)據(jù)及統(tǒng)計結(jié)果,從而為我們帶來準確的生產(chǎn)狀態(tài)結(jié)論。
動態(tài)路由: 以動態(tài)方式根據(jù)需要將請求路由至不同后端集群處。
壓力測試: 逐漸增加指向集群的負載流量,從而計算性能水平。
負載分配: 為每一種負載類型分配對應容量,并棄用超出限定值的請求。
靜態(tài)響應處理: 在邊緣位置直接建立部分響應,從而避免其流入內(nèi)部集群。
多區(qū)域彈性: 跨越AWS區(qū)域進行請求路由,旨在實現(xiàn)ELB使用多樣化并保證邊緣位置與使用者盡可能接近。
除此之外,Netflix公司還利用Zuul的功能通過金絲雀版本實現(xiàn)精確路由與壓力測試。
Spring Cloud已經(jīng)建立起一套嵌入式Zuul代理機制,從而簡化常見用例當中UI應用需要將調(diào)用代理至一項或者多項后端服務處的對應開發(fā)流程。這項功能對于要求將用戶界面代理至后端服務的用例而言極為便捷,其避免了管理CORS(即跨域資源共享)以及為全部后端進行獨立驗證等復雜流程。Zuul代理機制的一類重要應用在于實現(xiàn)API網(wǎng)關模式(如圖七所示)。
Spring Cloud對嵌入式Zuul代理進行了強化,從而使其能夠自動實現(xiàn)文件上傳處理。而與Spring Cloud Security配合之后,其能夠輕松實現(xiàn)OAuth2 SSO以及將令牌傳遞至下游服務等工作。Zuul利用Ribbon作為其客戶端與全部出站請求的負載均衡機制。Ribbon的動態(tài)服務器列表內(nèi)容通常由Eureka負責填充,但Spring Cloud也能夠通過其它來源填充該列表。Spring Cloud Lattice項目就已經(jīng)能夠通過輪詢Cloud Foundry Diego的Receptor API填充Ribbon的服務器列表。
跨入微服務領域的決定意味著我們將正式迎接分布式系統(tǒng)所帶來的諸多挑戰(zhàn),而分布式系統(tǒng)絕不是那種能夠“湊合使用”的方案。因此,我們必須假設系統(tǒng)內(nèi)各組件的行為及位置始終處于不斷變化當中,甚至經(jīng)常表現(xiàn)出不可預知狀態(tài)。在今天的文章中,我們已經(jīng)談到了幾種能夠幫助大家解決此類挑戰(zhàn)的現(xiàn)成模式,而且這些模式已經(jīng)在Netflix OSS與Spring Cloud得到切實驗證。我個人建議大家在著手建立理想中的“永遠運行、自我修復且具備可擴展能力”的系統(tǒng)方案之前,首先對它們進行一番嘗試與體驗。
- 1 回答
- 0 關注
- 785 瀏覽
添加回答
舉報