1 回答

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