微服務
此一新架構術語的定義
「微服務架構」一詞在過去幾年中突然出現,用來描述一種特定的軟體應用程式設計方式,即以獨立部署服務的套件形式。雖然此一架構風格沒有精確的定義,但仍有某些共同特質,例如圍繞業務功能組織、自動化部署、端點中的智慧,以及語言和資料的分散式控制。
2014 年 3 月 25 日
「微服務」——軟體架構擁擠街道上的另一個新名詞。儘管我們天生的傾向是用輕蔑的一瞥來略過此類事物,但這一點術語描述了一種軟體系統風格,我們發現它越來越有吸引力。我們在過去幾年中看到許多專案使用這種風格,而且迄今為止的結果都是正面的,以至於對我們許多同事而言,這正成為建構企業應用程式的預設風格。然而,遺憾的是,沒有太多資訊概述微服務風格是什麼以及如何執行。
簡而言之,微服務架構風格[1]是一種將單一應用程式開發為小型服務套件的方法,每個服務都在自己的程序中執行,並透過輕量級機制(通常是 HTTP 資源 API)進行通訊。這些服務以業務功能為基礎建構,並可透過全自動化部署機制獨立部署。這些服務的集中管理非常少,它們可以用不同的程式語言撰寫,並使用不同的資料儲存技術。
要開始說明微服務樣式,將其與單體樣式進行比較會很有幫助:單體應用程式建置為單一元件。企業應用程式通常建置為三個主要部分:客戶端使用者介面(包含 HTML 頁面和在使用者機器上的瀏覽器中執行的 JavaScript)、資料庫(包含插入到共用且通常為關聯式資料庫管理系統的許多資料表)和伺服器端應用程式。伺服器端應用程式會處理 HTTP 要求、執行網域邏輯、從資料庫擷取和更新資料,以及選擇和填入要傳送至瀏覽器的 HTML 檢視。這個伺服器端應用程式是一個單體,也就是單一的邏輯可執行檔[2]。對系統的任何變更都涉及建置和部署伺服器端應用程式的新版本。
這種單體伺服器是建置此類系統的自然方式。處理要求的所有邏輯都在單一程序中執行,讓您可以使用語言的基本功能將應用程式分為類別、函數和命名空間。只要小心,您就可以在開發人員的筆電上執行和測試應用程式,並使用部署管線來確保變更已適當地測試並部署到生產環境。您可以透過在負載平衡器後方執行許多執行個體來橫向擴充單體。
單體應用程式可能會成功,但人們對它們的挫折感與日俱增,特別是因為有更多應用程式部署到雲端。變更週期是綁在一起的,對應用程式的一小部分進行變更,需要重新建置和部署整個單體。隨著時間推移,通常很難維持良好的模組化結構,這使得將應只影響單一模組的變更保留在該模組中變得更加困難。擴充需要擴充整個應用程式,而不是擴充需要更多資源的部分。

圖 1:單體和微服務
這些挫折感導致微服務架構樣式:將應用程式建置為服務套件。除了服務可以獨立部署和擴充的事實外,每個服務還提供穩固的模組邊界,甚至允許使用不同的程式語言撰寫不同的服務。它們還可以由不同的團隊管理。
我們並未宣稱微服務風格是新穎或創新的,其根源至少可追溯至 Unix 的設計原則。但我們確實認為,考慮微服務架構的人還不夠多,而且許多軟體開發如果使用微服務架構,將會獲得更好的結果。
微服務架構的特質
我們無法說微服務架構風格有一個正式的定義,但我們可以嘗試描述我們認為符合標籤的架構的共同特徵。與任何描述共同特徵的定義一樣,並非所有微服務架構都具備所有特徵,但我們確實預期大多數微服務架構都展現出大多數特徵。雖然我們作者一直是這個相當鬆散社群的積極成員,但我們的目的是嘗試描述我們在自己工作中以及我們所知的團隊的類似工作中所看到的內容。特別是,我們並未制定任何定義以供遵循。
透過服務組成元件化
自從我們參與軟體產業以來,一直希望透過將元件插入在一起來建構系統,這與我們在實體世界中看到事物製作的方式非常類似。在過去的幾十年中,我們看到包含大多數語言平台中常見函式庫的大型彙編有相當大的進展。
在討論元件時,我們會遇到一個困難的定義,即是什麼讓一個元件成為元件。 我們的定義 是元件是一個可獨立替換和升級的軟體單元。
微服務架構將使用函式庫,但它們將自己的軟體元件化的主要方式是分解成服務。我們將函式庫定義為連結到程式中並使用記憶體中函式呼叫來呼叫的元件,而服務則是與機制(例如網路服務要求或遠端程序呼叫)通訊的非程序元件。(這與許多 OO 程式中的服務物件概念不同 [3]。)
將服務用作元件(而非函式庫)的主要原因之一是服務可以獨立部署。如果您有一個包含單一程序中多個函式庫的應用程式 [4],則對任何單一元件的變更都會導致必須重新部署整個應用程式。但如果該應用程式分解成多個服務,您可以預期許多單一服務變更只需要重新部署該服務。這並非絕對的,有些變更會變更服務介面,導致一些協調,但良好的微服務架構的目標是透過服務合約中的內聚服務界限和演進機制將這些變更減到最低。
使用服務作為組件的另一個後果是更明確的組件介面。大多數語言都沒有定義明確的已發布介面的良好機制。通常只有文件和紀律才能防止客戶端中斷組件的封裝,導致組件之間過度緊密的耦合。服務透過使用明確的遠端呼叫機制,讓避免這種情況變得更容易。
像這樣使用服務確實有缺點。遠端呼叫比處理中呼叫更昂貴,因此遠端 API 需要更粗略,這通常更難使用。如果您需要變更組件之間的責任分配,當您跨越處理程序界限時,這些行為的變更會更難執行。
在第一次近似中,我們可以觀察到服務對應到執行時間處理程序,但這僅是第一次近似。服務可能包含多個處理程序,這些處理程序將始終一起開發和部署,例如應用程式處理程序和僅由該服務使用的資料庫。
以業務功能為中心組織
在尋求將大型應用程式拆分為多個部分時,管理階層通常會專注於技術層面,導致產生 UI 團隊、伺服器端邏輯團隊和資料庫團隊。當團隊沿著這些界線分開時,即使是簡單的變更也可能導致跨團隊專案需要花費時間和預算核准。聰明的團隊將針對此進行最佳化,並選擇兩害相權取其輕的方案,只要將邏輯強制放入他們有權存取的任何應用程式即可。換句話說,邏輯無所不在。這是康威定律運作的一個範例。
任何設計系統(廣義定義)的組織都會產生一個設計,其結構是組織溝通結構的副本。
-- 梅爾文·康威,1968 年

圖 2:康威定律的運作
微服務的區分方法不同,會根據業務能力進行區分,並將其拆分為服務。此類服務採用軟體的廣泛堆疊實作,適用於該業務領域,包括使用者介面、持久性儲存和任何外部協作。因此,團隊是跨職能的,包括開發所需的所有技能範圍:使用者體驗、資料庫和專案管理。

圖 3:由團隊界限強化的服務界限
一家以這種方式組織的公司是www.comparethemarket.com。跨職能團隊負責建置和操作每個產品,每個產品都拆分為多項個別服務,透過訊息匯流排進行通訊。
大型單體應用程式也可以圍繞業務功能進行模組化,儘管這並非常見情況。我們肯定會敦促建立單體應用程式的龐大團隊沿著業務線進行劃分。我們在此看到的最大問題是,他們傾向於圍繞過多的內容進行組織。如果單體跨越這些模組化邊界的許多部分,團隊中的個別成員可能會難以將其納入短期記憶中。此外,我們看到模組化線條需要極大的紀律才能執行。服務元件所需的更明確分離使得團隊界限更清晰。
產品而非專案
我們看到的大多數應用程式開發工作都使用專案模型:目標是提供某個軟體部分,然後被視為已完成。在完成時,軟體會移交給維護組織,而建立它的專案團隊則會解散。
微服務支持者傾向於避免此模型,而偏好一個概念,即團隊應在其整個生命週期內擁有產品。一個常見的靈感來自亞馬遜的「你建立,你執行」概念,其中開發團隊對生產中的軟體負起全部責任。這讓開發人員每天都能接觸到他們的軟體在生產中的行為,並增加與使用者的接觸,因為他們必須承擔至少部分的支援負擔。
產品心態與業務功能的連結有關。與其將軟體視為一組要完成的功能,而是一種持續的關係,問題在於軟體如何協助其使用者提升業務能力。
沒有理由不能對單體應用程式採取相同的方法,但更細緻的服務可以更容易在服務開發人員和使用者之間建立個人關係。
智慧端點與愚笨管道
在不同的程序之間建立通訊結構時,我們看過許多產品和方法強調將大量的智慧放入通訊機制本身。一個很好的例子是企業服務匯流排 (ESB),其中 ESB 產品通常包含用於訊息路由、編排、轉換和應用業務規則的複雜設施。
微服務社群偏好一種替代方法:智慧終端和愚蠢管道。由微服務建構的應用程式旨在盡可能地解耦和內聚——它們擁有自己的網域邏輯,並在傳統 Unix 意義上更像過濾器——接收請求,適當地套用邏輯並產生回應。這些是使用簡單的 RESTful 協定編排的,而不是像 WS-Choreography 或 BPEL 這樣的複雜協定,或由中央工具進行編排。
最常使用的兩種協定是具有資源 API 的 HTTP 請求回應和輕量級訊息傳遞[7]。第一種的最佳表達方式是
成為網路的一部分,而不是躲在網路之後
-- Ian Robinson
微服務團隊使用建構萬維網(以及在很大程度上,Unix)的原則和協定。開發人員或操作人員通常可以毫不費力地快取經常使用的資源。
第二種常見方法是透過輕量級訊息匯流排傳遞訊息。所選擇的基礎架構通常很笨(笨到只充當訊息路由器) - RabbitMQ 或 ZeroMQ 等簡單實作所做的,除了提供可靠的非同步架構之外,並不多 - 智慧依然存在於產生和使用訊息的端點中;在服務中。
在巨石架構中,元件會執行於處理程序中,它們之間的通訊是透過方法呼叫或函式呼叫。將巨石架構轉換為微服務時最大的問題在於改變通訊模式。從記憶體內方法呼叫天真地轉換為 RPC 會導致不佳效能的冗長通訊。相反地,您需要以更粗略的方式取代細緻的通訊。
分散式治理
集中治理的後果之一是傾向於標準化在單一技術平台上。經驗顯示,這種方法具有限制性 - 並非每個問題都是釘子,也並非每個解決方案都是槌子。我們偏好使用適當的工具來執行工作,儘管巨石架構應用程式可以在某種程度上利用不同的語言,但這並不常見。
將巨石架構的元件拆分為服務後,在建構每個元件時,我們可以選擇。您想使用 Node.js 來建立一個簡單的報告頁面嗎?去做吧。使用 C++ 來建立一個特別棘手的近乎即時元件嗎?很好。您想換成不同類型的資料庫,以更好地符合一個元件的讀取行為嗎?我們有技術可以重建它。
當然,僅僅因為您可以做某事,並不表示您應該做 - 但以這種方式分割您的系統表示您有這個選項。
建構微服務的團隊也偏好不同的標準方法。他們偏好產生有用的工具,讓其他開發人員可以用來解決與他們面臨的類似問題,而不是使用某處以紙本寫下的一組已定義標準。這些工具通常會從實作中收集,並與更廣泛的群組分享,有時(但並非專屬地)使用內部開放原始碼模型。由於 git 和 github 已成為事實上的版本控制系統首選,開放原始碼實務在內部變得越來越普遍。
Netflix 是一個遵循此哲學的組織範例。分享有用且經過實戰考驗的程式碼作為函式庫,鼓勵其他開發人員以類似的方式解決類似問題,但如果需要,仍可選擇不同的方法。共用函式庫通常專注於資料儲存、程序間通訊等常見問題,以及我們在下面進一步討論的基礎架構自動化。
對於微服務社群來說,開銷特別沒有吸引力。這並不是說社群不重視服務合約。恰恰相反,因為服務合約往往更多。只是他們正在尋找不同的方式來管理這些合約。例如 容忍讀取器 和 消費者驅動合約 等模式通常會套用於微服務。這些模式有助於服務合約獨立演進。執行消費者驅動合約作為建置的一部分,可以增加信心,並快速回饋您的服務是否運作。事實上,我們知道澳洲有一個團隊使用消費者驅動合約來推動新服務的建置。他們使用簡單的工具,讓他們可以定義服務的合約。這會成為自動化建置的一部分,甚至在編寫新服務的程式碼之前。然後,服務僅建置到滿足合約為止,這是避免在建置新軟體時出現「YAGNI」[8] 困境的優雅方法。這些技術及其周邊的工具,透過減少服務之間的時間耦合,降低了對集中合約管理的需求。
分散式治理的巔峰可能是由 Amazon 推廣的建置它/執行它的精神。團隊負責軟體的所有面向,包括全天候執行軟體。這種責任下放絕對不是常態,但我們確實看到越來越多公司將責任推給開發團隊。Netflix 是另一個採用此精神的組織[10]。每晚 3 點被呼叫器叫醒,絕對是撰寫程式碼時專注於品質的強大誘因。這些想法與傳統的集中式治理模式相去甚遠。
分散式資料管理
資料管理的分散化以許多不同的方式呈現。在最抽象的層級上,這表示世界概念模型會因系統而異。這是整合大型企業時常見的問題,銷售部門對客戶的觀點會與支援部門不同。在銷售部門觀點中稱為客戶的一些事物可能完全不會出現在支援部門的觀點中。那些確實出現的事物可能具有不同的屬性,而(更糟的是)常見屬性具有微妙不同的語意。
這個問題在應用程式之間很常見,但也會發生在應用程式內部,特別是當該應用程式分成不同的元件時。思考這一點的一個有用方法是 Domain-Driven Design 中Bounded Context的概念。DDD 將複雜的網域分成多個受限的脈絡,並繪製出它們之間的關係。這個程序對單體和微服務架構都有用,但服務和脈絡邊界之間存在自然關聯,有助於釐清,並如我們在業務功能部分中所述,強化區分。
微服務除了分散概念模型的決策外,也分散資料儲存的決策。雖然單體應用程式偏好單一邏輯資料庫作為持續資料,但企業通常偏好單一資料庫橫跨各種應用程式,其中許多決策是由廠商圍繞授權的商業模式推動的。微服務偏好讓每個服務管理自己的資料庫,無論是同一個資料庫技術的不同實例,或是完全不同的資料庫系統,這種方法稱為多語持久性。你可以在單體中使用多語持久性,但它更常出現在微服務中。

分散微服務中資料的責任,對管理更新有影響。處理更新的常見方法是使用交易,以保證更新多個資源時的一致性。這種方法通常用於單體中。
像這樣使用交易有助於一致性,但會造成顯著的時間耦合,這在多個服務間是有問題的。分散式交易出了名的難以實作,因此微服務架構強調服務間的無交易協調,並明確承認一致性可能只是最終一致性,而問題則由補償操作來處理。
選擇以這種方式管理不一致性,對許多開發團隊來說是一個新的挑戰,但它通常符合業務實務。企業通常處理一定程度的不一致性,以便快速回應需求,同時具備某種逆轉程序來處理錯誤。只要修正錯誤的成本低於在更一致性下失去業務的成本,這種權衡就是值得的。
基礎設施自動化
基礎設施自動化技術在過去幾年有了長足的發展,特別是雲端和 AWS 的發展,降低了建置、部署和操作微服務的營運複雜性。
許多使用微服務建置的產品或系統,是由具有持續交付和其前身持續整合豐富經驗的團隊建置的。以這種方式建置軟體的團隊廣泛使用基礎設施自動化技術。這在下面所示的建置管線中說明。

圖 5:基本建置管線
由於這不是一篇關於持續交付的文章,我們將在此僅重點說明幾個關鍵功能。我們希望盡可能確信我們的軟體運作正常,因此我們執行大量的自動化測試。將運作正常的軟體推廣到管線「上」表示我們自動化部署到每個新環境。
單體應用程式將在這些環境中建立、測試並推播,而且相當順利。事實證明,一旦您投資自動化單體生產路徑,那麼部署更多應用程式似乎不再那麼可怕了。請記住,CD 的目標之一是讓部署變得無聊,因此無論是一或三個應用程式,只要它仍然無聊,就不重要[11]。
我們看到團隊使用廣泛基礎架構自動化的另一個領域是在生產中管理微服務。與我們上述的論點相反,只要部署無聊,單體和微服務之間就沒有太大的差別,但每種服務的作業環境可能截然不同。

圖 6:模組部署通常不同
為失敗而設計
使用服務作為組件的後果是,應用程式需要設計成能夠容忍服務故障。任何服務呼叫都可能因供應商不可用而失敗,客戶必須盡可能優雅地回應。與單體設計相比,這是一個缺點,因為它引入了額外的複雜性來處理它。後果是微服務團隊不斷思考服務故障如何影響使用者體驗。Netflix 的 Simian Army 在工作日誘發服務甚至資料中心的故障,以測試應用程式的復原力與監控。
這種在生產中的自動化測試足以讓大多數作業小組感到不寒而慄,通常會在休假前一週出現。這並不是說單體架構樣式無法進行複雜的監控設定 - 只是根據我們的經驗較不常見。
由於服務隨時都可能發生故障,因此快速偵測故障並在可能的情況下自動還原服務非常重要。微服務應用程式非常重視應用程式的即時監控,檢查架構元素(例如資料庫每秒收到多少要求)和與業務相關的指標(例如每分鐘收到多少訂單)。語意監控可以提供早期預警系統,警告發生問題,並觸發開發團隊追蹤和調查。
這對於微服務架構特別重要,因為微服務偏好編排和事件協作,這會導致出現行為。雖然許多專家讚揚意外出現的價值,但事實是,出現行為有時可能是件壞事。監控對於快速發現不良出現行為至關重要,以便可以修復它。
巨石可以建置成與微服務一樣透明 - 事實上,它們應該是如此。不同之處在於,您絕對需要知道在不同程序中執行的服務何時會中斷連線。對於同一個程序中的函式庫,這種透明性不太可能是有用的。
微服務團隊會希望看到每個個別服務都有精密的監控和記錄設定,例如顯示上線/下線狀態的儀表板,以及各種營運和與業務相關的指標。斷路器狀態、目前吞吐量和延遲的詳細資料,是我們在實際情況中經常遇到的其他範例。
演化式設計
微服務實務人員通常來自演化設計背景,並視服務分解為進一步的工具,讓應用程式開發人員能夠控制其應用程式的變更,而不會減慢變更速度。變更控制不一定要表示減少變更,只要具備正確的態度和工具,就能對軟體進行頻繁、快速且控制良好的變更。
每當您嘗試將軟體系統分解為組件時,就會面臨如何分割各個部分的決策,我們根據哪些原則決定將應用程式切片?組件的主要特性是獨立替換和可升級性的概念[12],這表示我們尋找可以重新編寫組件而不影響其合作者的點。事實上,許多微服務群組進一步明確預期許多服務會被廢棄,而不是長期演進。
Guardian 網站是一個很好的範例,說明一個設計和建置為單體的應用程式,但已朝微服務方向演進。單體仍然是網站的核心,但他們偏好透過建置使用單體 API 的微服務來新增新功能。這種方法對於本質上暫時的特色特別方便,例如處理運動賽事的專門頁面。網站的這類部分可以使用快速開發語言快速組合,並在活動結束後移除。我們在金融機構中看過類似的做法,其中會新增服務以迎合市場機會,並在幾個月甚至幾週後捨棄。
這種對可替換性的強調是模組化設計更一般原則的一個特例,也就是透過變更模式來推動模組化[13]。您希望將同時變更的事物保留在同一個模組中。系統中很少變更的部分應該與目前正在經歷大量變動的部分分開在不同的服務中。如果您發現自己重複一起變更兩個服務,這表示它們應該合併。
將組件放入服務中會增加更細緻的版本發布規劃機會。對於單體,任何變更都需要建置並部署整個應用程式。然而,對於微服務,您只需要重新部署您修改的服務。這可以簡化並加速版本發布流程。缺點是您必須擔心對一個服務的變更會導致其使用者中斷。傳統的整合方法是嘗試使用版本控制來處理這個問題,但在微服務世界中,偏好是僅將版本控制作為最後的手段。我們可以透過設計服務以盡可能容忍其供應商的變更,來避免許多版本控制。
微服務是未來嗎?
撰寫本文的主要目的是說明微服務的主要概念和原則。透過花時間執行此項工作,我們明確認為微服務架構風格是一個重要的概念,值得企業應用認真考量。我們最近使用此風格建置了數個系統,並且知道其他也使用並支持此方法的人。
我們所知道以某種方式開創架構風格的先驅包括 Amazon、Netflix、The Guardian、英國政府數位服務、realestate.com.au、Forward 和 comparethemarket.com。2013 年的研討會巡迴中充斥著許多公司轉向可歸類為微服務的範例,包括 Travis CI。此外,還有許多組織長期以來一直在執行我們會歸類為微服務的工作,但從未使用過這個名稱。(這通常標記為 SOA,儘管如我們所說,SOA 有許多相互矛盾的形式。 [14])
然而,儘管有這些正面的經驗,我們並非主張我們確定微服務是軟體架構的未來方向。雖然到目前為止,我們的經驗與單體應用程式相比是正面的,但我們意識到我們尚未經過足夠的時間來做出全面的判斷。
通常,您在做出架構決策後幾年,才會顯現出真正的後果。我們看過一些專案,一個擁有強大模組化渴望的優秀團隊,建構了一個隨著時間推移而衰敗的單體架構。許多人相信微服務不太可能發生這種衰敗,因為服務邊界是明確且難以修補的。然而,在我們看到足夠多且夠久的系統之前,我們無法真正評估微服務架構如何成熟。
當然有理由預期微服務會成熟不良。在任何組件化的努力中,成功取決於軟體如何適應組件。很難確切找出組件邊界應該在哪裡。演化設計承認了設定邊界的困難,因此強調易於重構它們的重要性。但是,當您的組件是具有遠端通訊的服務時,重構比使用處理中函式庫困難得多。跨服務邊界移動程式碼很困難,任何介面變更都需要參與者之間協調,需要新增後向相容性層,而且測試變得更複雜。
另一個問題是,如果組件無法乾淨地組成,那麼您所做的只是將複雜性從組件內部轉移到組件之間的連接。這不僅僅是移動複雜性,而是將其移動到一個不太明確且更難控制的地方。當您查看小型、簡單組件的內部時,很容易認為事情會更好,同時卻忽略了服務之間的混亂連接。
最後,還有團隊技能的因素。新的技術往往會被更熟練的團隊採用。但是,對更熟練的團隊更有效的方法不一定適用於技能較差的團隊。我們看過許多技能較差的團隊建構混亂的單體架構的案例,但需要時間才能看出這種混亂發生在微服務時會發生什麼事。一個差勁的團隊永遠會建立一個差勁的系統 - 在這種情況下,很難判斷微服務是減少了混亂還是讓它變得更糟。
我們聽過一個合理的論點,就是不應該從微服務架構開始。相反地,從單體開始,保持模組化,並且在單體成為問題時將其拆分為微服務。(儘管此建議並非理想,因為良好的處理中介面通常不是良好的服務介面。)
因此,我們謹慎樂觀地撰寫這篇文章。到目前為止,我們已經對微服務風格有了足夠的了解,認為這是一條值得踏上的道路。我們無法確定我們最終會在哪裡,但軟體開發的挑戰之一是,你只能根據目前手邊不完美資訊來做出決策。
註腳
1: 「微服務」一詞是在 2011 年 5 月於威尼斯附近舉辦的軟體架構師工作坊中討論的,用來描述參與者認為許多人最近都在探討的共同架構風格。2012 年 5 月,同一群人決定將「微服務」定為最合適的名稱。詹姆士在 2012 年 3 月於克拉科夫舉辦的第 33 度研討會中,以案例研究的方式提出了一些這些想法,主題為微服務 - Java,Unix 風格,而弗雷德喬治也在差不多同一時間提出了類似的看法。Netflix 的艾德里安考克羅夫特將這種方法描述為「細粒度 SOA」,並在網路規模上率先採用這種風格,就像本文中提到的許多其他人一樣 - 喬沃爾尼斯、丹尼爾特霍斯特諾斯、伊凡博徹和葛拉漢塔克利。
2: Unix 社群已經使用「單體」一詞一段時間了。它出現在Unix 程式設計藝術中,用來描述過於龐大的系統。
3: 包括我們在內的許多物件導向設計師,在領域驅動設計中使用服務物件一詞,表示執行未繫結到實體的重要程序的物件。這與我們在本文中使用「服務」的方式不同。很遺憾地,「服務」一詞具有這兩種含義,我們必須接受這個多義詞。
4: 我們認為 應用程式是一種社會建構,它結合了程式碼庫、功能群組和資金。
5: 我們忍不住要提到 Jim Webber 的說法,他認為 ESB 代表 "錯誤的義大利麵盒"。
6: Netflix 明確地建立了連結 - 直到最近才將其架構風格稱為細粒度的 SOA。
7: 在規模的極端情況下,組織通常會轉向二進位制通訊協定 - 例如 protobufs。使用這些協定的系統仍然展現出智慧終端、愚笨管道的特性 - 並以透明度換取規模。大多數網路屬性和絕大多數企業不需要進行這種取捨 - 透明度可能帶來巨大的好處。
8: "YAGNI" 或 "You Aren't Going To Need It" 是 XP 原則,也是在需要之前不要新增功能的勸告。
9: 我們聲稱單體是單一語言有點不誠實 - 為了在今日的網路建構系統,您可能需要知道 JavaScript 和 XHTML、CSS、您選擇的伺服器端語言、SQL 和 ORM 方言。這絕非單一語言,但您知道我們的意思。
10: Adrian Cockcroft 特別在 這場精彩的簡報 中提到 "開發人員自助服務" 和 "開發人員執行他們撰寫的程式"(原文如此),該簡報於 2013 年 11 月在 Flowcon 發表。
11: 我們在這裡有點不誠實。顯然,部署更多服務、在更複雜的拓撲中部署服務比部署單一單體更困難。幸運的是,模式可以降低這種複雜性 - 但投資於工具仍然是必須的。
12: 事實上,Daniel Terhorst-North 稱這種風格為可替換元件架構,而不是微服務。由於這似乎符合我們偏好的某些特性,因此我們偏好後者。
13: Kent Beck 在 實作模式 中將此重點列為他的設計原則之一。
14: 而且 SOA 幾乎不是這段歷史的根源。我記得當 SOA 術語在世紀初出現時,人們說「我們已經做了很多年了」。其中一個論點是,這種風格將其根源視為 COBOL 程式在企業運算最早時期透過資料檔案進行通訊的方式。在另一個方向上,有人可能會辯稱微服務與 Erlang 程式設計模型相同,但應用於企業應用程式環境中。
參考文獻
雖然這不是一份詳盡的清單,但有許多來源讓從業者獲得靈感或支持本文中所述的類似哲學。
部落格和線上文章
- Clemens Vasters 在 microsoft 上的雲端部落格
- David Morgantini 在其部落格上對此主題的介紹
- 來自 Heroku 的 12 要素應用程式
- 英國政府數位服務設計原則
- Jimmy Nilsson 的部落格和在 infoq 上關於雲端區塊運算的文章
- Alistair Cockburn 關於六角形架構
書籍
- 釋出
- Rest 在實務中
- Web API 設計(免費電子書)。Brian Mulloy,Apigee。
- 企業整合模式
- Unix 程式設計藝術
- 由測試引導的成長導向物件軟體
- 現代公司:組織設計以提升效能和成長
- 持續交付:透過建置、測試和部署自動化進行可靠的軟體釋出
- 領域驅動設計:處理軟體核心的複雜性
簡報
- 沒有架構師的架構。Erik Doernenburg。
- 這樣我的公車看起來很大嗎?。Jim Webber 和 Martin Fowler,QCon 2008
- 游擊 SOA。Jim Webber,2006
- 有效交付的模式。Daniel Terhorst-North,2011。
- Adrian Cockcroft 的 slideshare 頻道.
- 九頭蛇和超媒體。Ian Robinson,JavaZone 2010
- 正義將採取數百萬個複雜的行動。Leonard Richardson,Qcon 2008。
- Java,UNIX 方式。James Lewis,JavaZone 2012
- 微服務架構。Fred George,YOW!2012
- Democratising attention data at guardian.co.uk。Graham Tackley,GOTO Aarhus 2013
- Functional Reactive Programming with RxJava。Ben Christensen,GOTO Aarhus 2013(需要註冊)。
- Breaking the Monolith。Stefan Tilkov,2012 年 5 月。
論文
- L. Lamport,「可靠分散式多處理系統的實作」,1978 年 http:// research.microsoft.com/en-us/um/people/lamport/pubs/implementation.pdf
- L. Lamport、R. Shostak、M. Pease,「拜占庭將軍問題」,1982 年(可於)http:// www.cs.cornell.edu/courses/cs614/2004sp/papers/lsp82.pdf 取得
- R.T. Fielding,「架構樣式與基於網路的軟體架構設計」,2000 年 http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm
- E. A. Brewer,「邁向強健的分散式系統」,2000 年 http://www.cs.berkeley.edu/ ~brewer/cs262b-2004/PODC-keynote.pdf
- E. Brewer,「CAP 十二年後:『規則』如何改變」,2012 年,http:// www.infoq.com/articles/cap-twelve-years-later-how-the-rules-have-changed
進一步閱讀
上述清單擷取了我們最初在 2014 年初撰寫本文時所使用的參考。如需取得最新資訊來源清單,請參閱 微服務資源指南。
重大修訂
2014 年 3 月 25 日:微服務是未來嗎?的最後一期
2014 年 3 月 24 日:新增演化設計部分
2014 年 3 月 19 日:新增基礎架構自動化和故障設計部分
2014 年 3 月 18 日:新增分散式資料部分
2014 年 3 月 17 日:新增分散式治理部分
2014 年 3 月 14 日:新增智慧終端與愚蠢管道部分
2014 年 3 月 13 日:新增產品而非專案部分
2014 年 3 月 12 日:新增圍繞業務功能組織部分
2014 年 3 月 10 日:發布第一期