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