- 微服務架構原理與開發實戰
- 張剛編著
- 3060字
- 2024-01-22 18:20:45
1.4.2 微服務架構的特點
1.1節的微服務定義大致反映出微服務架構的一些特點:微服務是小的服務;微服務是獨立運行的;微服務的交互是輕量級的,是可以跨語言的;服務的設計是圍繞業務的;微服務是可以自動部署的,有集中式的服務管理等。
但隨著微服務的發展,它的定義是多變的,每個人在使用微服務架構時的做法都不完全一樣,其中有很多很好的實踐,有復雜的,也有簡單的,似乎很難去界定誰對誰錯,畢竟由于軟件項目的獨特性,每種實踐都是在特定的需求和場景下產生的,因此不妨把目光放在它們的共同點上。此前有過無數人的大膽嘗試和實踐,我們可以通過分析來看看大多數人都在怎樣做著微服務。
ThoughtWorks的Martin Fowler是業界的權威專家,他認為雖然很難給微服務的架構一個正確的定義,但可以嘗試描述我們認為有合適標簽的架構的共同特征。并非所有的微服務架構都具有所有的特征,但是Martin Fowler希望大多數微服務能具有大部分特征。最后,他總結了微服務的九大特征,成為當下這個松散的社區關于微服務的一個寬松的標準。
下面就來看看微服務的九大特征,如圖1.8所示。

圖1.8 微服務的九大特征
1. 服務組件化
組件簡單來說就是一個可以獨立更換和升級的軟件單元,就像計算機的內存、顯卡、硬盤一樣,是可插拔的,而且更換和設計不會影響其他單元。在微服務架構設計中,我們將應用拆分為一個個獨立的服務,這些服務像組件一樣可以獨立更換和升級。每個服務擁有獨立的進程,可以獨立開發和部署;每個服務可以擁有獨立的存儲,服務之間通過HTTP等輕量級的通信協議進行交互,而不是傳統的嵌入式的方式。
2. 圍繞業務組織團隊
通常,傳統的公司可能會按照技術去組建團隊,如測試團隊、前端開發團隊、后端開發團隊、數據庫團隊、運維團隊等,但微服務本身的設計是圍繞業務展開的,各個服務按照業務價值來劃分邊界,這樣就導致了微服務的團隊組織結構上是必須跨技術能力的,一個團隊中可能需要包括各種能力的人,如前業務分析師、測試工程師、前端開發工程師、后端開發工程師、數據庫工程師、UI設計師、運維工程師等。
當然,由于微服務小的設計理念,團隊的規模不會很大,如亞馬遜的“Two Pizza Team”原則,一個團隊吃一餐飯只需兩個披薩就夠了。這樣一個團隊,工作中的內耗是很低的,因為團隊的職責邊界更加清晰,團隊間溝通不暢或者推卸責任等現象將會得到改善。
3. 做產品而非項目
微服務架構中流行著一句話:“You build,you run it!”意思是你構建的應用,那么由你來負責運行它。
人們在傳統的軟件項目中,往往以一個做交付的方式來做項目,而不會考慮整個產品的運作方式或生命周期。例如,產品將需求交付給開發,開發將應用交付給測試,測試將構建好的版本交付給運維,運維負責將應用運行起來。
微服務架構的團隊組織可以說是麻雀雖小五臟俱全,一個團隊往往需要負責項目的全部階段的工作,微服務團隊更像是在做產品而非項目,大家需要關注整個產品的生命周期,負責各個階段的各種工作,并且持續關注服務的運作情況,從而不斷分析,來幫助客戶提升業務價值,倡導開發運維一體化,現在很流行的DevOps等角色,也是在微服務流行趨勢下所產生的。
4. 智能端點和啞管道
由于微服務本身分離的特點,它并不能像單體式架構那樣通過本地的函數調用即可進行服務間的交互,那么選擇一個好的遠程調用的通信方式是關鍵。
在SOA中,有一些較好的實踐,如在1.2.3節中提到的ESB就強調需要將調用邏輯放入溝通機制本身,各個端點遵循統一的標準,由企業服務總線來完成消息路由、編排和轉換等功能。這會導致服務間的通信更加煩瑣,笨重的調用方式在服務升級或更換時顯得尤為吃力。所以,我們需要更加粗粒度、更加輕量的通信機制。
微服務社區更傾向于采用另一種方法:智能端點和啞管道。微服務在設計上不只是在意分離,還強調內聚,每個服務擁有自己的領域邏輯,就像是UNIX的管道設計一樣。目前最常用的有兩種協議:一種是帶有資源API的HTTP請求,即人們常說的RESTful API請求;另一種是通過輕量級的消息總線,如使用RabbitMQ或ZeroMQ等來進行消息傳遞。
5. 去中心化治理
無論是單體式架構,還是SOA,似乎都需要定義一個統一的技術平臺標準,但經驗表明,這種做法并不好,不是每個問題都是釘子,不是每個解決方案都是錘子,每種技術平臺都會有它的短板,一旦規定了統一的技術平臺標準,在遇到它的短板時,開發者將感到十分痛苦。
微服務團隊更提倡采用不同的方法或標準,使用正確的工具和技術來完成工作。通過輕量級的、粗粒度的通信機制,不同的服務不再需要中心化的技術平臺標準,服務可以是不同語言、不同框架的,可以根據不同的業務場景需要來選擇合適的技術。
6. 分散的數據管理
分散的數據管理十分符合微服務最初的定義,服務間是獨立運行的,每個服務都可以擁有自己獨立的存儲。當然,關于去中心化數據管理,業界也有很多解決方案,如模型概念上的不同,可以抽象出不同的視圖,可以使用領域驅動設計的方式(后面章節會介紹)將復雜的領域劃分成不同的限界上下文,這有助于澄清業務邊界,強化數據模型上的分離。
微服務除在概念模型上的分散策略之外,還分散了數據的存儲決策,讓每個服務管理自己的數據庫,可以是相同的數據庫技術的不同實現,也可以是完全不同的數據庫系統。人們把這種方式稱為“Polyglot Persistence”(多語言持久化)。
當然,這種做法也會帶來一些弊端,如分布式事務等問題,往往需要通過額外的工作來保證事務的最終一致性,但是這絲毫不會阻礙其在微服務架構中的應用,微服務團隊往往把這個問題的解決寄希望于服務拆分的合理性上。
7. 基礎設施自動化
微服務由于小和分離的特點,往往一個大型復雜的項目運作需要部署很多服務,如果都是人工手動來完成這項工作,那么無疑將會耗費巨大的成本,而且人工容易出錯,一旦出錯,排查會十分費力,好在基礎設施自動化技術在過去幾年中發生了巨大的變化,特別是云技術、Docker和K8s等技術的發展,大大降低了構建、部署和運行軟件的成本。
各種持續集成和持久交付的工具層出不窮,而微服務架構中就需要這樣的服務或技術工具來保證服務的構建、部署和測試等工作可以做到自動化。
8. 容錯設計
使用服務作為組件的結果就是需要設計的應用程序能夠容忍服務的失敗。由于服務提供者不可用,任務服務消費者調用此服務時都可能失敗,因此服務消費者必須盡可能優雅地對此做出響應。
單體式架構在這方面似乎有一定的優勢,由于都是本地函數調用,它無須引入額外的復雜代碼就可達到優雅響應的目的,但任何事情都有其多面性,單體式架構的優點是系統復雜度降低了,但缺點也是毋庸置疑的。也就是說,如果服務不可用,可能會影響整個應用,致使其他無關的功能都不可用。
所以,微服務架構中一般最基本的做法是針對每個服務都進行彈性的監控和日志記錄,這樣能夠保證在服務出現故障時快速地監控并加以恢復。有關斷路器、當前吞吐量和延遲的信息監控等其他方式,在后續的章節中詳細介紹。
9. 演進式設計
現在已經知道了很多微服設計的關鍵因素,不難看出,要設計一個完美的微服務架構,尤其是對于沒有足夠經驗的團隊來說,無疑是很難的。但從軟件設計的思路來看,沒有設計從一開始就是完美的。
所以,很多情況下,微服務從業者都會以演進的方式進行系統的設計,筆者在工作中也常被項目的業務分析師問道:為什么我看你們總在重構,就不能一開始寫代碼時把結構設計好嗎?這時,筆者反而覺得這是軟件設計好的表現,然后很耐心地和他解釋軟件設計的思路就是這樣的。人們稱其為演進式設計。
當然,重構也是需要條件的,開發人員應該能夠控制應用程序的更改,而且不會降低變更速度。變更控制并不一定意味著改變,但可以通過正確的態度和工具,如單元測試、契約測試等,對軟件進行頻繁、快速和良好控制的更改。