微服務生態的四層模型

微服務生態的四層模型

第1層:硬件層

硬件層是微服務生態的底層。這一層是服務器物理機所在的層,它們是所有微服務運行的基礎。這些服務器被放置在數據中心的機架上,由供電系統供給電力,使用着昂貴的冷卻系統。它們有些是某些公司私有的,有些是從所謂的“雲服務提供商”那裏租來的,比如 AWS EC2、GCP、阿里雲等。

是自己購買服務器還是選擇雲服務器並不容易選擇,它需要考慮購買成本、可用性、可靠性和運營成本。

管理服務器是硬件層的職責之一。每臺服務器都需要安裝標準的操作系統。使用哪種操作系統並沒有一個標準答案,這完全取決於要構建的應用程序、構建應用程序所使用的語言以及構建微服務所需要的軟件包和工具。主流的微服務生態系統一般會使用 Linux 的變形版本,比如 CentOS、Debian 或 Ubuntu,不過一個使用了 .NET 平臺的公司顯然會有不同的選擇。

操作系統的安裝和硬件資源的配置是服務器的第一個層。每個主機必須被配置好,而且在安裝好操作系統之後,必須提供一個配置管理工具(比如 Ansible、Chef 或 Puppet)來安裝應用程序,並做好必要的配置。

對主機進行主機級別的監控(使用Nagios)是有必要的,而且需要記錄主機級別的日誌。在主機出現異常(磁盤錯誤、網絡或CPU過載)時就可以方便地對它們進行診斷,有助於問題的解決。

第2層:通信層

通信層到生態系統的所有層,因爲微服務之間的交互會在多個層上進行,所以很難清晰地對通信層與其它層之間的邊界進行定義。雖然難以清晰地定義它們之間的邊界,但是這個層所涉及的元素是很明確的。一般包含網絡、DNS、RPC和API端點、服務發現、服務註冊以及負載均衡。

RPC、端點和消息傳遞

微服務通過遠程過程調用(RPC)或消息傳送與其他微服務進行交互,這些調用通過網絡發送到其他微服務的API端點上(如果使用的是消息傳遞,消息會被髮送到消息代理,消息代理會對這些消息進行路由)。基本原理是這樣的:使用一個特定的協議,一個微服務把符合特定格式的數據通過網絡發送到另一個服務(或者是另一個微服務的API端點)或消息代理上(消息代理確保數據會被路由到其他微服務的API端點上)。

微服務有幾種通信方式,第一種是最常用的HTTP+REST/Thrift。如果使用的是這種方式,各個服務使用超文本傳輸協議(HTTP)進行網絡交互,它們向特定的REST端點(使用各種HTTP方法,比如GET、POST等)或Thrift端點發送請求或從這些端點接收響應。發送的數據一般是JSON(或protool buffer)格式。

第二種通信方式是消息傳遞。消息傳遞是異步(非阻塞)的,不過相對複雜。消息傳遞的工作原理是這樣的:一個微服務把數據(消息)通過網絡(HTTP或其他)發送給一個消息代理,消息代理會把消息路由到其他微服務上。

消息傳遞也有幾種模式,最流行的兩種分別是發佈訂閱以及請求和響應。如果使用的是發佈和訂閱模式,客戶端會訂閱一個主題,它將從主題上收到發佈者發佈的任何一個消息。請求和響應模式就更直接了,客戶端發送一個請求到一個服務(或消息代理)上,這個服務會對這個請求作出響應。有些消息中間件同時支持兩種模式,比如ApacheKafka。

消息傳遞有幾個缺點需要注意。消息傳遞不會比HTTP+REST具備更強的伸縮性,如果你的系統對伸縮性有要求的話一定要清楚這一點。消息傳遞對變更不友好,因爲它是集中式的,這樣會導致消息隊列和消息代理變成整個生態系統的故障點。它的異步特性在併發環境裏會導致競賽條件,如果沒有處理好,還會出現無限循環。在使用消息傳遞時,如果能夠處理好上述這些問題,他會變得跟同步解決方案同樣穩定和高效。

服務發現、服務註冊和負載均衡

在單體應用架構裏,所有的業務流量都被髮送給負載均衡器,然後被分發到應用服務器上。而在微服務架構裏,業務流量被路由到大量不同的應用程序上,然後再被分發給部署了特定微服務的服務器。爲了能夠高效地實現上述場景,微服務架構需要在通信層實現三項技術:服務發現、服務註冊和負載均衡。

一般來說,如果微服務A需要向微服務B發起請求,那麼微服務A需要知道微服務B的IP地址和端口。微服務的通信層需要知道這些微服務的IP地址和端口,才能正確地路由這些請求。這個問題可以通過服務發現(比如etcd、Consul、Hyperbahn 或 Zookeeper)來解決,服務發現可以確保請求會被路由到它們本該去的地方,而且只會被路由到正常運行的實例上(這非常重要)。服務發現需要用到服務註冊,服務註冊中記錄了生態系統裏所有微服務的IP地址和端口。

在微服務架構裏,在對微服務進行橫向擴展和重新部署時(比如使用了像Apache Mesos再這樣的硬件抽象層),端口和IP地址會發生變化。在這種情況下,可以考慮爲每個微服務分配一個靜態端口。

除非你的所有微服務都部署在同一個實例上(一般不太可能),否則需要在通信層使用負載均衡。簡單地說,負載均衡可以做到:如果你有10個微服務實例,負載均衡器(軟件或硬件)可以確保業務流量(均衡地)分發到所有的實例上。在微服務生態系統裏,只要涉及請求轉發,都需要用到負載均衡器,這意味着一個大型的微服務生態系統將包含多層負載均衡。常見的負載均衡器有 Amazon Web Services Elastic Load Balancer、Netflix 的 Eureka 和 Nginx。

第3層:應用平臺層

應用平臺層是微服務生態系統的第3層,這一層包含了所有獨立於微服務的內部工具和服務。這一層所包含的集中式和服務跨越了整個生態系統,因爲有了這些工具和服務,微服務開發團隊就可以把精力集中在微服務的開發上。

一個好的應用平臺需要爲開發者提供一套內部的自助工具,包括標準化的開發流程、集中式的自動化構建和發佈系統、自動化測試、標準化和集中式的部署方案以及集中式的日誌和微服務級別的監控。這些元素的細節此處不進行探討,不過我們也會簡要地介紹其中的幾個元素,闡述一些基本的概念。

內部自助開發工具

有很多東西可以被納入內部自助開發工具的範疇,它們是否可以被歸納爲這類工具不僅取決於開發者對工具的需求,還要考慮基礎設施和生態系統的整體抽象度和複雜性。決定使用哪一種工具,首先要對責任領域進行切分,然後對開發者所要完成的任務進行評估,以便設計、構建和維護他們的服務。

在一個已經使用了微服務架構的公司裏,給工程師團隊指派職責要十分謹慎。最簡單的做法是爲微服務生態系統的每一個層組件一個工程子團隊。這些工程子團隊將負責處理它們所在層的所有相關事務:運維團隊負責第1層,基礎設施團隊負責第2層,應用平臺團隊負責第3層,微服務團隊負責第4層。

在這種組織結構裏,工作在上層的工程師需要使用自助工具對下層的一些東西進行配置。例如,負責消息服務的團隊應該爲其他開發者提供一個自助工具,當微服務團隊的開發者需要爲他們的服務配置消息系統時,他們就可以使用這個工具,而無需過多地瞭解紛繁複雜的消息系統。

使用這些集中式的自助工具是由原因的。在一個多元化的微服務生態系統裏,一個團隊的普通工程師對其他團隊的系統和服務並不瞭解(或知之甚少),他們也不可能稱爲面面俱到的專家。每個開發人員只對自己負責的部分比較瞭解,但從整個生態系統來看,這些開發人員組合在一起就無所不知了。爲生態系統的每一部分構建易用的用戶界面,爲開發人員提供相關的培訓,以便教會他們如何使用這些工具,而不是試圖讓每個開發人員瞭解這些工具和服務紛繁複雜的內部細節。把所有的事情放到一個黑匣子裏,然後提供詳細的說明文檔。

使用這些工具的第二個理由是,你不需要其他團隊的人來對你的服務和系統做任何關鍵性的改動,因爲這些人可能會給你們帶來麻煩。對於底層(第1層、第2層和第3層)的服務來說,更是如此。讓他們在這些層上面做出改動,或者要求(更糟糕的是期待)他們成爲某方面的專家有可能會釀成大禍。舉一個配置管理的例子:不具備相關專門知識的微服務團隊開發人員對系統配置做了一些變更,這有可能導致大規模的服務癱瘓,因爲他們所做的變更有可能不只是影響到它們自己的服務。

開發週期

開發人員在對已有微服務進行修改或構建新的微服務時,對開發流程進行流水線化、標準化和自動化可以大幅提升開發效率。有些東西需要被放在微服務生態系統的第3層,讓穩定可靠的開發成爲可能。

首先是集中式的版本控制系統,這個系統保存了所有代碼,允許對代碼進行跟蹤、版本管理和搜索。這個可以通過一些工具來實現,比如 GitHub 或者自有的 git 或 svn 代碼倉庫,可以將這些倉庫和一些協作工具集成起來,比如 Phabrictor,以簡化代碼的維護和審查工作。

其次是穩定高效地開發環境。總所周知,在微服務生態系統裏實現一個這樣的開發環境是很困難的,因爲微服務之間的依賴太過複雜。不過它們都是最基本的因素,我們無法避免。一些工程組織傾向於本地完成開發工作(在開發人員的電腦上),不過這樣會導致糟糕的部署,因爲開發人員並不清楚他們修改的代碼是如何被部署到生產環境的。最穩定可靠的構建開發環境的方式是爲生產環境創建一個鏡像(不是爲了預生產,也不是爲了收集反饋,更不是爲了生產),這個鏡像包含所有複雜的依賴關係鏈。

測試、構建、打包和發佈

開發過程中的測試、構建、打包和發佈應該儘量被標準化和集中化。在開發結束之後,當有代碼變更被提交,需要運行相關的測試用例,然後自動構建和打包即將發佈的新版本。這個時候,持續集成工具就可以派上用場,一些現成的解決方案(比如Jenkins)不僅功能齊全而且使用方便。這些工具可以讓整個過程自動化,幾乎不留給人類任何犯錯的機會。

部署管道

在經過了開發、測試、構建、打包和發佈這些步驟之後,部署管道是新代碼走向生產環境的另一個流程。在一個微服務生態系統裏,部署會在很短的時間內變得極其複雜,每天上百個部署都是很平常的事。開發團隊需要爲開發構建工具,並對開發過程進行標準化。

日誌和監控

所有的微服務都應該把它們的請求和響應相關的重要信息記錄到日誌裏。因爲微服務變更的速度太快,如果系統發生了錯誤,重建當時的系統狀態變得很困難,導致代碼的缺陷難以重現。使用微服務級別的日誌可以幫助開發人員更好地瞭解他們的服務在過去某個時刻或當前時刻的狀態。在微服務級別對微服務的關鍵度量指標進行監控也是出於同樣的目的:實時準確的監控可以幫助開發人員瞭解服務的狀態和健康狀況。

第4層:微服務層

微服務生態系統的頂層是微服務層。這一層是微服務以及微服務所有相關事物所在的層,它與底下的基礎設施層完全分離,比如硬件、部署、服務發現、負載均衡和通信。微服務層唯一沒有被分離的是使用自助工具所做的配置。

在軟件工程裏,應用的配置一般會被集中化,針對某個工具或某些工具(配置管理、資源隔離或部署工具)的配置可以和這些工具保存在一起。例如,應用程序的自定義部署配置一般會和部署工具的代碼保存在一起,而不是和應用程序的代碼保存在一起。這種方式對單體應用架構或小型的微服務生態系統來說是沒有問題的,但在包含了大量微服務和內部工具(每個工具都有自定義的配置)的大型微服務生態系統裏,這種方式就會造成混亂:處在上層的微服務團隊需要修改處在下層的工具代碼,他們會經常忘記哪些地方包含了配置信息(或者不包含)。爲了解決這個問題,可以把與微服務相關的配置放在微服務代碼庫裏,然後開放給下層的工具和系統訪問。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章