微服務應該多大

2021-10-20 10:42:01 字數 3031 閱讀 2728

**:

該文章和作者很厲害.

微服務實踐最常見的錯誤之一是把微服務做得過小。本文通過示例,深入討論了微服務的大小和粒度。

微服務架構終於成為一種架構模式。與任何新技術一樣,微服務的發展符合 gartner 的技術曲線。從推特上獲得的資訊來看,它處於低谷期或復甦的早期階段。換句話說,過去6年,我們在構建微服務方面積累了一些重要經驗,其一就是確保以恰當的方式考慮每個微服務的範圍。

眾所周知,微服務容易把人往「溝裡帶」,並沒有解決實際問題。當你想到「微服務」一詞時,首先看到的是字首「微」(micro)。據 an introduction to greek 一書的介紹,在柏拉圖和亞里斯多德那裡,μικρός只表示少或小。在日常英語中,「微」往往表示小得異乎尋常的東西——畢竟,「微公尺」是一公尺的百萬分之一,而「顯微鏡」是用來觀察那些肉眼看不見的東西,因為它們尺寸太小。

問題就出在這種不同的認知上。與之前的大型單體服務相比,微服務應該是「小」的。然而,它不應該太小——把微服務做得過小是很多團隊實現微服務架構時遇到的最常見錯誤之一。

正是這種「微服務必須非常小」的思想導致這個問題。關於微服務,我們經常聽到的另乙個抱怨是,在銀行等複雜領域使用它們太難了,因為所需的 rest 或訊息傳遞介面沒有提供跨多個微服務進行兩階段提交的方法。每當我們聽到這種抱怨時,頭腦中的警鐘就會響起——通常,這種抱怨是乙個症狀,表明團隊把他們的微服務看作是非常微小的東西。

為解決這個問題,讓我們從乙個簡單的示例開始尋找解決方法,然後再回過頭來,進一步考慮該解決方案對整個微服務架構的影響。

示例從設計乙個簡單的 account 服務開始,從這個沒有包含微服務實現的設計開始,以便你能看清它的演進過程。假設團隊正在使用領域驅動設計(稍後會詳細介紹),在他們的第一次嘗試中,發現 account 實體需要引用兩個關聯依賴實體——entry 和 owner。

最初的 account 設計

很快,團隊就發現 account 上有一些定義良好的操作:借、貸、開、關。幸運的是,這些操作可以很好地對映到 rest 介面,因此,採用這種簡單的基於實體的設計並將其對映到微服務實現起來比較容易。然而,他們很快就發現問題——他們還沒有弄清楚賬戶之間如何進行轉賬,如下圖所示:

具有 transfer 服務的 account 設計

問題是,在賬戶之間轉賬需要乙個全新的 rest 介面,這一點顯而易見。問題是如何實現,這是否代表乙個全新的微服務?

最簡單的假設是(也是許多團隊都會採用的假設),微服務和 rest 介面之間應該存在 1 對 1 對映。然而,當把這個對映關係應用示例中時,我們很快就遇到乙個問題:新的微服務如何實現?最簡單的方法似乎是讓 transfer 微服務呼叫 account 微服務兩次;一次從「from」賬戶借出,一次貸入「to」賬戶。所以,我們的實現可能是這樣的:

呼叫其他服務的服務實現

但這將陷入前面討論過的兩階段提交問題!如果借出成功,貸入失敗,那麼這個客戶賬戶裡的錢就少了,還沒有任何追索權。這種情況顯然是不可接受的;因此,許多團隊嘗試了以下解決方案:

在資料庫引入耦合的 account 設計

這解決了兩階段提交問題,但是在資料庫中引入耦合,違反了微服務設計的原則之一,即服務應該擁有自己的資料,而不是通過共享資料庫「隱式」耦合。正確的做法是什麼呢?在我看來,許多團隊都「走遠了」,並開始追求涉及 saga 模式的解決方案,以便通過補償事務來處理問題。雖然 saga 模式可以解決問題,但它不是這種簡單情況的最優解決方案。

考慮一下下面的解決方案,它打破了之前的那個假設:

在服務邊界暴露多個服務

在這個解決方案中,我們重新考慮了之前假設的那個約束——乙個微服務正好對應於乙個 rest 介面。這個假設已經寫入網路上的許多微服務教程中。然而,如果你仔細閱讀 fowler 的原始**,就會發現其中從未指出過這個假設。在微服務邊界上可以暴露多個服務。但這並不是這個小練習的真正目的。讓我們回到主題,通過這個練習來闡明更常見的問題。

在這方面,團隊是對的。我們看到,在微服務設計領域,其中乙個最大的問題是,他們經常不是從領域驅動設計這樣的技術開始,而是從其他地方開始,比如從現有系統的設計開始,並試圖從那裡得出自己的微服務。或者,從乙個架構開始(通常以工具和框架的形式指定),然後嘗試讓微服務「有機地」發展。在這兩種情況下,最終得到的都不是我所說的微服務——它們往往非常注重技術,與企業業務完全無關。

而我們所說的微服務是用業務術語描述的「業務微服務」,業務人員可以識別它們,並可以從設計中找到它們。設計不足的症狀之一是解決方案中很少或基本沒有業務微服務,這是因為沒有從業務詞彙表開始設計。從業務詞彙表開始設計是至關重要的一步,這就是為什麼我們建議所有構建微服務的團隊將領域驅動設計作為其設計過程的一部分。

如果不首先從業務詞彙表入手,那麼通常會搞成如下架構:

你們很多人看到這個可能會說「這到底有什麼問題嗎?」這看起來就是我們要的微服務架構!要回答這個問題,我們必須回顧下 fowler 在他最初關於微服務的**中提出的觀點。他和 lewis 提出的觀點是,當你的團隊由技術專家組成時,所生產的軟體也將按技術領域進行組織——這就是實踐中的康威定律。fowler 的解決方案是,按業務能力組織跨職能團隊。

當你開發乙個與上文類似的微服務架構時,就已經回到了微服務本來要解決的問題!你不僅重新建立了乙個單體,而且還是乙個分布式單體,情況變得更糟糕了。這違反了可能是 martin 寫過的最重要的一句話:

fowler 的分布式物件第一定律:不要使用分布式物件。
那麼,更好的架構應該是什麼樣的呢?首先在最上層,考慮下垂直畫線,而不是水平畫線。

微服務 微服務簡介

什麼是微服務 顧名思義,就是粒度較小的服務,不再侷限於系統與系統之間的藉口呼叫,也不侷限於某種具體的服務形式。系統中凡是可被復用的功能模組都可以被 服務化 轉變為 服務 這些服務可以對外暴露,也可能僅限於再系統內部使用。由於服務數量更多,粒度更小,因此管控難度會更大,對效能的要求也更高。微服務的好處...

微服務與微服務架構

微服務 微服務強調的是服務的大小,它關注的是某乙個點,是具體解決某乙個問題 提供落地對應服務的乙個服務應用,狹意的看,可以看作eclipse裡面的乙個個微服務工程 或者module。例如 訂單服務 支付服務 微服務架構 馬丁.福勒 martin fowler 微服務架構介紹 微服務架構是 種架構模式...

python 微服務 python微服務方案

使用python做web開發面臨的乙個最大的問題就是效能,在解決c10k問題上顯的有點吃力。有些非同步框架tornado twisted gevent 等就是為了解決效能問題。這些框架在效能上有些提公升,但是也出現了各種古怪的問題難以解決。在python3.6中,官方的非同步協程庫asyncio正式...