什麼是微服務?

類別: IT

過去幾年來,“微服務架構”這個術語出現了,它描述了一種將軟體應用程式設計為可獨立部署的服務套件的特定方式。儘管這種架構風格沒有確切的定義,但圍繞業務能力,自動化部署,端點智慧以及語言和資料的分散控制等方面存在著某些共同特徵。

 “微服務” - 在軟體架構擁擠的街道上又一個新名詞。儘管我們的自然傾向是以輕蔑的眼光來傳遞這樣的東西,但這些術語描述了一種我們發現越來越吸引人的軟體系統風格。我們已經看到許多專案在過去幾年中都採用了這種風格,迄今為止的結果是積極的,因此對於我們的許多同事來說,這正成為構建企業應用程式的預設風格。可悲的是,沒有太多的資訊概述了微服務的風格以及如何去做。

簡而言之,微服務架構風格[1]是一種將單應用程式作為一套小型服務開發的方法,每種應用程式都在其自己的程式中執行,並與輕量級機制(通常是HTTP資源的API)進行通訊。這些服務是圍繞業務功能構建的,可以通過全自動部署機制進行獨立部署。這些服務的集中化管理已經是最少的,它們可以用不同的程式語言編寫,並使用不同的資料儲存技術。

在開始介紹微服務風格(microservice style)前,比較一下整體風格(monolithic style)是很有幫助的:一個完整應用程式(monolithic application)構建成一個單獨的單元。企業應用程式通常建立在三個主要部分中:一個客戶端使用者介面(由使用者計算機上的瀏覽器中執行的HTML頁面和JavaScript組成)資料庫(包括插入常見的通常是關聯式資料庫管理的多個表系統)和一個伺服器端應用程式。伺服器端應用程式將處理HTTP請求,執行特定領域邏輯,通過資料庫進行檢索和更新資料,選擇並填充要傳送到瀏覽器的HTML檢視。這個伺服器端應用程式是一個龐然大物 - 一個邏輯可執行檔案[2]。系統的任何更改都涉及構建和部署新版本的伺服器端應用程式。 

這樣的整體服務(monolithic server)是一種構建系統很自然的方式。處理請求的所有邏輯都在一個程式中執行,允許您使用語言的基本功能將應用程式劃分為類,函式和名稱空間。謹慎操作時,您可以在開發人員的膝上型電腦上執行和測試應用程式,並使用部署通道來確保更改經過適當測試並部署到生產環境中。您可以通過在負載平衡器後面執行多個例項來橫向縮放整體。

單體式應用程式可以取得成功,但越來越多的人會感到失望 - 尤其是隨著更多應用程式被部署到雲中。變更週期是連在一起的 - 對應用程式的一小部分進行更改,需要重建和部署整個程式。隨著時間的推移,它通常很難保持良好的模組化結構,使得難以保持應該:模組內的一個改動僅影響該模組本身中。自適應需要自適應整個應用程式,而不是它的一部分,這樣做需要更多資源。

圖1: 單體式和微服務

這些挫折引出了微服務架構風格:將應用程式構建為服務套件。除了服務是可獨立部署和可伸縮的事實之外,每個服務還提供了一個嚴格的模組邊界,甚至允許用不同的程式語言編寫不同的服務。它們也可以由不同的團隊來管理。

我們並不是說微服務風格是新穎的或創新的,它的根源至少可以追溯到Unix的設計原則。但我們確實認為,沒有足夠多的人考慮使用微服務架構,如果他們使用了,那麼許多軟體開發將會更好。

微服務體系結構的特徵

我們不能說對微服務架構風格有一個正式的定義,但是我們可以嘗試描述我們所看到的與“微服務”標籤相符的架構的共同特徵。與任何概述共同特徵的定義一樣,並不是所有的微服務架構都具有所有的特徵,但是我們確實期望大多數微服務架構具有大多數特徵。雖然我們的作者一直是這個相當鬆散的社群的活躍成員,但我們的目的是嘗試描述我們在自己的工作中看到的東西,以及我們所知道的團隊的類似努力。特別地,我們並沒有給出一些符合要求的定義。

通過服務(Sevice)實現元件化

只要我們參與過軟體行業,這就存在一種期盼:通過將元件整合在一起來構建系統,這與我們在現實世界中看待事物的方式非常相似。在過去的幾十年中,我們已經見證了大部分語言平臺中常見庫的大量摘要所取得的巨大進步。

在談及元件時,我們遇到了對元件構成定義的難題。我們的定義是,元件是可獨立更換和升級的軟體單元。

微服務架構一樣會用到各種庫,但這種架構會把軟體給拆分成各種不同的服務來實現元件化。這裡我們定義兩個重要的概念: (library) 指的是連結到程式的元件,通過本地函式呼叫來使用庫提供的功能;而服務 (service) 是程式外的元件,通過網路服務請求 (web service request) 或者遠端函式呼叫之類的機制來使用裡面的功能。注意這和很多物件導向程式裡服務物件的機制是不同的 [3]

之所以在元件化的軟體裡用服務,而不是庫,一個主要原因就是各個服務是可以獨立部署的。比如說,如果在同一個軟體 [4] 裡用了多個庫,那麼就算只是修改了其中一個,都會導致整個軟體要被重新部署;相反,如果用的是服務,那隻需要重新部署修改過的就可以。然而,有個問題是,當修改服務時,可能會把服務介面也給修改了,這樣一來,服務的呼叫者和開發者就得自己私下協調了。好的微服務架構,就應該儘量避免這種問題;非要修改服務契約的話,也得循序漸進,讓呼叫者有跡可循,不用私下協調。

使用服務作為元件的另一個後果是更顯式的元件介面。大多數語言都沒有很好的機制來定義顯式釋出的介面。通常,只有文件和規程可以防止客戶機破壞元件的封裝,從而導致元件之間的緊密耦合。通過使用顯式的遠端呼叫機制,服務可以更容易地避免這種情況。
使用這樣的服務確實有缺點。遠端呼叫比程式內呼叫更昂貴,因此遠端api需要粗粒度,這通常更難以使用。如果您需要更改元件之間的職責分配,那麼當您跨越流程邊界時,這種行為的移動就更加困難了。

我們可以觀察到服務對映到執行時程式,但這只是第一次近似。服務可能包括多個程式,這些程式將始終會一起開發和部署,例如應用程式和服務所用到的資料庫。

根據服務能力進行管理

當將大型應用程式拆分為不同元件時,通常的管理側重於技術層,由技術層引領UI團隊、伺服器端邏輯團隊和資料庫團隊的工作。當團隊的這種生產線被隔離時,即使是簡單的改變也會引起跨團隊的專案耗時耗力。聰明的團隊將圍繞這一點進行優化——僅把邏輯強加到他們所能觸及的任何方式中。換句話說,邏輯無處不在。這是Conway定律[5]的一個例子。

任何如設計系統(廣義定義)的組織,必將創造出一個設計,其設計結構是組織的通訊結構的副本。

-- Melvyn Conway, 1967

圖2: 實際中的Conway法則

在劃分層面,微服務方法是不同的,分解成圍繞業務能力所組織的服務。這些服務需要對該業務領域的軟體進行廣泛的實施,包括使用者介面、永續性儲存和任何外部協作。因此,團隊是跨職能的,包括開發所需的全部技能:使用者體驗、資料庫和專案管理。

圖3: 由團隊邊界所加強的服務邊界

什麼是微服務?原文請看這裡