設計微服務架構前應該了解的 5 項指導原則
對於從微服務開始的團隊來說,最大的挑戰之一就是堅持 金髮女孩原則 (該典故來自於童話《金髮姑娘和三隻熊》):不要太大,不要太小,不能太緊密耦合。之所以是挑戰的部分原因是會對究竟什麼是設計良好的微服務感到疑惑。
數十位 CTO 通過採訪分享了他們的經驗,這些對話說明了設計良好的微服務的五個特點。本文將幫助指導團隊設計微服務。(有關詳細信息,請查看即將出版的書籍 Microservices for Startups,LCTT 譯註:已可免費下載完整的電子版)。本文將簡要介紹微服務的邊界和主觀的 「規則」,以避免在深入了解五個特徵之前就開始指導您的微服務設計。
微服務邊界
使用微服務開發新系統的核心優勢之一是該體系結構允許開發人員獨立構建和修改各個組件,但在最大限度地減少每個 API 之間的回調數量方面可能會出現問題。根據 SparkPost 工程副總裁 Chris McFadden 所說,解決方案是應用適當的服務邊界。
關於邊界,與有時難以理解和抽象的領域驅動設計(DDD,一種微服務框架)形成鮮明對比,本文重點介紹了和我們行業的一些頂級 CTO 一同建立的明確定義的微服務邊界的實用原則。
避免主觀的 「規則」
如果您閱讀了足夠多的關於設計和創建微服務的建議,您一定會遇到下面的一些 「規則」。 儘管將它們用作創建微服務的指南很有吸引力,但加入這些主觀規則並不是思考確定微服務的邊界的原則性方式。
「微服務應該有 X 行代碼」
讓我們直說:微服務中有多少行代碼沒有限制。微服務不會因為您寫了幾行額外的代碼而突然變成一個獨石應用。關鍵是要確保服務中的代碼具有很高的內聚性(稍後將對此進行更多介紹)。
「將每個功能轉換為微服務」
如果函數基於三個輸入值計算某些內容並返回結果,它是否是微服務的理想候選項?它是否應該是單獨可部署應用程序?這確實取決於該函數是什麼以及它是如何服務於整個系統。將每個函數轉換為微服務在您的情景中可能根本沒有意義。
其他主觀規則包括不考慮整個情景的規則,例如團隊的經驗、DevOps 能力、服務正在執行的操作以及數據的可用性需求。
精心設計的服務的 5 個特點
如果您讀過關於微服務的文章,您無疑會遇到有關設計良好的服務的建議。簡單地說,高內聚和低耦合。如果您不熟悉這些概念,有許多文章關於這些概念的文章。雖然它們提供了合理的建議,但這些概念是相當抽象的。基於與經驗豐富的 CTO 們的對話,下面是在創建設計良好的微服務時需要牢記的關鍵特徵。
1:不與其他服務共享資料庫表
在 SparkPost 的早期,Chris McFadden 和他的團隊必須解決每個 SaaS 業務需要面對的問題:它們需要提供基本服務,如身份驗證、帳戶管理和計費。
為了解決這個問題,他們創建了兩個微服務:用戶 API 和帳戶 API。用戶 API 將處理用戶帳戶、API 密鑰和身份驗證,而帳戶 API 將處理所有與計費相關的邏輯。這是一個非常合乎邏輯的分離 —— 但沒過多久,他們發現了一個問題。
McFadden 解釋說,「我們有一個名為『用戶 API』的服務,還有一個名為『帳戶 API』的服務。問題是,他們之間實際上有幾個來回的調用。因此,您會在帳戶服務中執行一些操作,然後調用並終止於用戶服務,反之亦然」
這兩個服務的耦合太緊密了。
在設計微服務時,如果您有多個服務引用同一個表,則它是一個危險的信號,因為這可能意味著您的資料庫是耦合的源頭。
這確實是關於服務與數據的關係,這正是 Swiftype SRE,Elastic 的負責人 Oleksiy Kovrin 告訴我。他說,「我們在開發新服務時使用的主要基本原則之一是,它們不應跨越資料庫邊界。每個服務都應依賴於自己的一組底層數據存儲。這使我們能夠集中訪問控制、審計日誌記錄、緩存邏輯等。」
Kovrin 接著解釋說,如果資料庫表的某個子集「與數據集的其餘部分沒有或很少連接,則這是一個強烈的信號,表明該組件可以被隔離到單獨的 API 或單獨的服務中」。
Lead Honestly 的聯合創始人 Darby Frey 與此的觀點相呼應:「每個服務都應該有自己的表並且永遠不應該共享資料庫表。」
2:資料庫表數量最小化
微服務的理想尺寸應該足夠小,但不能太小。每個服務的資料庫表的數量也是如此。
Scaylr 的工程主管 Steven Czerwinski 在接受採訪時解釋說 Scaylr 的最佳選擇是「一個或兩個服務的資料庫表。」
SparkPost 的 Chris McFadden 表示同意:「我們有一個 suppression 微服務,它處理、跟蹤數以百萬計和數十億圍繞 suppression 的條目,但它們都非常專註於圍繞 suppression,所以實際上只有一個或兩個表。其他服務也是如此,比如 webhooks。
3:考慮有狀態和無狀態
在設計微服務時,您需要問問自己它是否需要訪問資料庫,或者它是否是處理 TB 級數據 (如電子郵件或日誌) 的無狀態服務。
Algolia 的 CTO Julien Lemoine 解釋說:「我們通過定義服務的輸入和輸出來定義服務的邊界。有時服務是網路 API,但它也可能是使用文件並在資料庫中生成記錄的進程 (這就是我們的日誌處理服務)。」
事先要明確是否有狀態,這將引導一個更好的服務設計。
4:考慮數據可用性需求
在設計微服務時,請記住哪些服務將依賴於此新服務,以及在該數據不可用時的整個系統的影響。考慮到這一點,您可以正確地設計此服務的數據備份和恢復系統。
Steven Czerwinski 提到,在 Scaylr 由於關鍵客戶行空間映射數據的重要性,它將以不同的方式複製和分離。
相比之下,他補充說,「每個分片信息,都在自己的小分區里。如果部分客戶群體因為沒有可用日誌而停止服務那很糟糕,但它隻影響 5% 的客戶,而不是100% 的客戶。」
5:單一的真實來源
設計服務,使其成為系統中某些內容的唯一真實來源。
例如,當您從電子商務網站訂購內容時,則會生成訂單 ID,其他服務可以使用此訂單 ID 來查詢訂單服務,以獲取有關訂單的完整信息。使用 發布/訂閱模式,在服務之間傳遞的數據應該是訂單 ID ,而不是訂單本身的屬性信息。只有訂單服務具有訂單的完整信息,並且是給定訂單信息的唯一真實來源。
大型團隊的注意事項
考慮到上面列出的五個注意事項,較大的團隊應了解其組織結構對微服務邊界的影響。
對於較大的組織,整個團隊可以專門擁有服務,在確定服務邊界時,組織性就會發揮作用。還有兩個需要考慮的因素:獨立的發布計劃和不同的正常運行時間的重要性。
Cloud66. 的 CEO Khash Sajadi 說:「我們所看到的微服務最成功的實現要麼基於類似領域驅動設計這樣的軟體設計原則 (如面向服務的體系結構),要麼基於反映組織方法的設計原則。」
「所以 (對於) 支付團隊」 Sajadi 說,「他們有支付服務或信用卡驗證服務,這就是他們向外界提供的服務。所以這不一定是關於軟體的。這主要是關於為外界提供更多服務的業務單位。」
雙披薩原理
Amazon 是一個擁有多個團隊的大型組織的完美示例。正如在一篇發表於 API Evangelist 的文章中所提到的,Jeff Bezos 向所有員工發布一項要求,告知他們公司內的每個團隊都必須通過 API 進行溝通。任何不這樣做的人都會被解僱。
這樣,所有數據和功能都通過該介面公開。Bezos 還設法讓每個團隊解耦,定義他們的資源,並通過 API 提供。Amazon 正在從頭建立一個系統。這使得公司內的每一支團隊都能成為彼此的合作夥伴。
我與 Iron.io 的 CTO Travis Reeder 談到了 Bezos 的內部倡議。
「Jeff Bezos 規定所有團隊都必須構建 API 才能與其他團隊進行溝通,」 Reeder 說。「他也是提出『雙披薩』規則的人:一支團隊不應該比兩個比薩餅能養活的大。」
「我認為這裡也可以適用同樣的方法:無論一個小型團隊是否能夠開發、管理和富有成效。如果它開始變得笨重或開始變慢,它可能變得太大了。」 Reeder 告訴我。
最後注意事項: 您的服務是否具有合適的大小和正確的定義?
在微服務系統的測試和實施階段,有一些指標需要記住。
指標 #1: 服務之間是否存在過度依賴?
如果兩個服務不斷地相互回調,那麼這就是強烈的耦合信號,也是它們可能更好地合併為一個服務的信號。
回到 Chris McFadden 的例子, 他有兩個 API 服務,帳戶服務和用戶服務不斷地相互通信, McFadden 提出了一個合併服務的想法,並決定將其稱為 「賬戶用戶 API」。事實證明,這是一項富有成效的戰略。
「我們開始做的是消除這些內部 API 之間調用的鏈接,」 McFadden 告訴我。「這有助於簡化代碼。」
指標 #2: 設置服務的開銷是否超過了服務獨立的好處?
Darby Frey 解釋說,「每個應用都需要將其日誌聚合到某個位置,並需要進行監視。你需要設置它的警報。你需要有標準的操作程序,和在出現問題時的操作手冊。您必須管理 SSH 對它的訪問。只是為了讓一個應用運行起來,就有大量的基礎性工作必須存在。」
關鍵要點
設計微服務往往會讓人感覺更像是一門藝術,而不是一門科學。對工程師來說,這可能並不順利。有很多一般性的建議,但有時可能有點太抽象了。讓我們回顧一下在設計下一組微服務時要注意的五個具體特徵:
- 不與其他服務共享資料庫表
- 資料庫表數量最小化
- 考慮有狀態和無狀態
- 考慮數據可用性需求
- 單一的真實來源
下次設計一組微服務並確定服務邊界時,回顧這些原則應該會使任務變得更容易。
via: https://opensource.com/article/18/4/guide-design-microservices
作者:Jake Lumetta 選題:lujun9972 譯者:lixinyuxx 校對:wxy
本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive