為何要用微服務方式建置應用程式?

針對軟體發展人員,將應用程式分解成元件元件並不是什麼新功能。 通常是透過一種分層方法,有後端存放區、中間層商務邏輯和前端使用者介面 (UI)。 過去幾年來的變化,是身為開發人員的我們開始為雲端建置分散式應用程式。

以下是一些不斷變化的商務需求:

  • 大規模建置和運作的服務,以便觸達位於新地理區域中的客戶。
  • 更快速提供特色與功能,靈活地回應客戶的需求。
  • 提高資源使用率來降低成本。

這些商務需求會影響我們「如何」 建置應用程式。

如需 Azure 使用微服務之方式的詳細資訊,請參閱 Microservices: An application revolution powered by the cloud (微服務︰採用雲端技術的應用程式革命)

單體式與微服務設計方法

應用程式會隨著時間而演化。 成功的應用程式因為有實用性而演化。 失敗的應用程式不會進化,且最終會被取代。 問題在於:您現在對需求了解多少,且這些需求在未來會有何變化? 例如,假設您要建置公司內某部門的報告應用程式。 您確定應用程式只適用於貴公司的範圍內,而且報表不會長期保留。 那麼,您的方法就會與要建置將視訊內容傳遞給數千萬客戶的服務不同。

有時候,以概念證明的形式取得大門就是驅動因素。 您知道您可以稍後重新設計應用程式。 從來不用卻過度設計並沒有太大意義。 另一方面,公司建置雲端時都會期望成長和使用量。 成長和規模無法預期。 我們想要快速建立原型,同時也知道我們是在可以處理未來成功的路徑上。 這是精簡的創業方法:建置、測量、學習及反覆執行。

在主從架構的時代,我們傾向專注於建立分層式應用程式,每一層都採用特定的技術。 已針對這些方法衍生出「單體式」應用程式一詞。 介面通常存在於各層之間,而在各層內的元件之間採用更緊密結合的設計。 開發人員設計並分解類別,將類別編譯成程式庫,然後連結起來成為一些可執行檔和 DLL。

這類單體式設計方法有一些優點。 單體式應用程式的設計方式通常比較簡單,且元件之間的呼叫通常會透過處理序間通訊 (IPC) 進行而變得更快。 此外,每個人都會測試單一產品,這通常會更有效率地使用人力資源。 缺點是分層式層級之間的結合緊密,以致您無法調整個別的元件。 如果您需要執行修正或升級,則必須等候其他人完成其測試。 更難進行敏捷化。

微服務解決這些缺點,更密切配合上述的商務需求。 但是它們也有優缺點。 微服務的優點在於其通常會封裝較簡單的商務功能,因此您可以獨立地對它們進行擴大或縮小、測試、部署,以及管理。 微服務方法的一個重要優點,在於團隊會比較偏向由商務案例所驅動。 較小的小組會採用他們想要使用的任何技術,根據客戶案例來開發微服務。

換句話說,組織不需要為了維護微服務應用程式而將技術標準化。 擁有服務的個別團隊可以根據團隊的專業知識,或什麼是最適合所要解決的問題,各自發揮所長。 實際上,最好有一組建議的技術,例如特定的 NoSQL 存放區或 Web 應用程式架構。

微服務的缺點是您必須管理更多不同的實體,並處理更複雜的部署和版本控制。 微服務之間的網路流量會增加,而相對應的網路延遲也會增加。 經過大量論述之後,可知細微的服務是效能夢魘的解決良方。 如果沒有工具協助檢視這些相依性,很難「看見」整個系統。

標準會讓微服務方法奏效、在通訊方式上達成共識,以及只在乎您需要從服務取得什麼,而不是僵固的合約。 必須在設計的初期定義這些聯繫,因為服務會各自獨立地更新。 另一個在設計微服務方法時出現的描述是「細緻的服務導向架構 (SOA)」。

簡而言之,微服務設計方法是低耦合的服務同盟,各自獨立變更,並達成一致的通訊標準。

隨著更多雲端應用程式的產生,人們發現這種將整體應用程式分解成獨立、以案例為焦點之服務的做法,在長期上是較好的方法。

應用程式開發方法的比較

Service Fabric platform application development

  1. 單體式應用程式包含領域特定功能,通常會依功能層來劃分,例如網路、商務和資料。

  2. 單體式應用程式可藉由複製到多部伺服器/虛擬機器/容器上進行擴充。

  3. 微服務應用程式會將個別功能分隔成個別較小的服務。

  4. 微服務方法可獨立部署每個服務而相應放大,跨伺服器/虛擬機器/容器建立這些服務的執行個體。

使用微服務方法來設計並非所有專案的萬靈丹,但確實較符合稍早所述的商務目標。 如果您知道稍後將有機會將程式碼修改成微服務設計,或許可接受從單體方式開始著手。 較常見的情況是您從單體式應用程式開始著手,然後從需要更高調整性或靈活度的功能領域開始,分階段緩慢地將它拆解。

使用微服務方法代表您會以許多小型服務來組成應用程式。 這些服務會在部署於電腦叢集的容器中執行。 較小的團隊會開發著重於某個案例且獨立測試的服務、進行各服務的控制版本、部署和調整規模,所以應用程式可以整體演化。

什麼是微服務?

有不同的微服務定義。 但大部分的微服務特性都已廣泛接受:

  • 封裝客戶或商務案例。 您遇到什麼問題?
  • 由小型工程團隊開發。
  • 使用任何程式設計語言撰寫並使用任何架構。
  • 由獨立控制版本、部署及調整的程式碼和 (選擇性) 狀態所組成。
  • 透過定義完善的介面和通訊協定,與其他微服務互動。
  • 具有可用來解析位置的唯一名稱 (URL)。
  • 在失敗時維持一致且可用的。

總而言之:

微服務應用程式是由獨立控制版本和可調整的客戶焦點式服務所組成,這些服務透過標準通訊協定和定義完善的介面彼此通訊。

使用任何程式設計語言撰寫並使用任何架構

身為開發人員,我們應該根據本身的技術或服務需求,自由選擇我們想建立的語言或架構。 在某些服務中,您可能認為 C++ 的效能優點勝於一切。 針對其他人,您從 C# 或 JAVA 取得的簡化受控開發可能更重要。 在某些情況下,您可能需要使用特定的合作夥伴程式庫、資料儲存技術,或向用戶端公開服務的方式。

選擇技術之後,您必須考慮服務的營運或生命週期管理和調整。

允許獨立控制版本、部署及調整的程式碼和狀態

不論您選擇何種方式來撰寫微服務,程式碼 (和選擇性的狀態) 都應該獨立地部署、升級及調整。 這個問題很難解決,因為這是您選擇的技術。 在調整方面,很不容易了解如何分割 (或分區化) 程式碼和狀態。 當程式碼和狀態使用不同的技術時 (目前的普遍情況),微服務的部署指令碼必須能夠同時調整兩者。 這也關乎靈活度和彈性,如此您就能升級部分微服務,而不需一次全部升級。

讓我們回到我們的整合型和微服務方法的比較。 下圖顯示儲存狀態的方法差異:

這兩種方法的狀態儲存體

Service Fabric platform state storage

左邊的單體式方法有單一資料庫和多層的特定技術。

右邊的微服務方法有圖形顯示互連的微服務,其中狀態通常以微服務為範圍,並會使用各種技術。

在單體式方法中,應用程式通常會使用單一資料庫。 使用一個資料庫的優點是它會在單一位置,讓部署工作變得更容易。 每個元件可以有單一資料表來儲存其狀態。 挑戰之處在於團隊必須嚴格區分狀態。 無可避免地,有人會想將新的資料行新增至現有的客戶資料表、在資料表之間執行聯結,以及對儲存層形成相依性。 發生這種情況後,您無法調整個別的元件。

在微服務方法中,每個服務都會管理並儲存自己的狀態。 每個服務負責同時調整程式碼和狀態,以滿足服務的需求。 缺點就是在需要建立應用程式資料的檢視或查詢時,您必須在多個狀態存放區上進行查詢。 通常由一個獨立的微服務建置一個跨許多微服務的檢視可解決此問題。 如果您需要在資料上執行多個即席查詢,則您應該考慮將每個微服務資料寫入資料倉儲服務,供離線分析。

微服務已建立版本。 不同版本的微服務可能會並存執行。 新版本的微服務可能會在升級期間失敗,並需要被回復至較舊的版本。 版本控制也對執行 A/B 測試很有幫助,其中不同的使用者會體驗到不同版本的服務。 比方說,在更廣泛推出新功能之前,通常會先針對一組特定的客戶升級微服務以測試新功能。

透過定義完善的介面和通訊協定,與其他微服務互動

在過去 10 年來所發佈的大量服務導向架構文獻中,皆已說明通訊模式。 一般而言,服務通訊使用 REST 方法,並搭配 HTTP 和 TCP 通訊協定及 XML 或 JSON 做為序列化格式。 從介面的觀點來看,它是關於採用 Web 設計方法。 但並不禁止您使用二進位通訊協定或您自己的資料格式。 如果這些通訊協定和格式無法公開取得,您的微服務會較難使用,要有心理準備。

具有可用來解析位置的唯一名稱 (URL)

只要您的微服務正在執行,就必須是可定址的。 如果您正在考慮機器及哪一部要執行特定的微服務,很快就會陷入困境。

就像 DNS 會解析特定電腦的特定 URL 一樣,微服務需要有唯一的名稱,其目前所在的位置才可被探索。 微服務需要有可定址的名稱,該名稱必須獨立於其執行所在的基礎結構。 這表示服務的部署方式與探索方式之間會有互動,因為需要有服務登錄。 當電腦故障時,登錄服務必須告訴您服務已移到哪個位置。

失敗時維持一致且可用

處理未預期的失敗是最難解決的問題之一,尤其在分散式系統中。 我們撰寫為開發人員的大部分程式碼都是處理例外狀況。 在測試期間,我們也會花費最多時間處理例外狀況。 流程比撰寫程式碼來處理失敗更複雜。 當執行微服務的電腦故障時,該怎麼辦? 您必須偵測失敗,這是本身的困難問題。 但您也需要重新啟動微服務。

基於可用性的原因,微服務必須能夠從失敗中復原,並能在另一部電腦上重新啟動。 除了這些復原需求以外,資料也不會遺失,而且資料必須保持一致。

如果在應用程式升級期間發生失敗,會使復原性很難達成。 在搭配部署系統一起運作時,微服務不需要復原。 它需要判斷是否可以繼續升級到較新版本,還是復原為舊版來維護一致的狀態。 您需要考慮一些問題,例如,是否有足夠的電腦可繼續升級,以及如何復原舊版的微服務。 需要微服務發出健康情況資訊,才能做出這些決定。

報告狀況和診斷

微服務必須報告其健全狀況和診斷,這一點看似明顯,但卻經常被輕忽。 如果沒這麼做,您將會很難從作業觀點上取得其健康情況的見解。 相互關聯一組獨立服務上的診斷事件,並處理電腦時間差異以了解事件順序,是一件非常具挑戰性的任務。 與您透過同意的通訊協定和資料格式來與微服務互動相同,您需要將健康情況和診斷事件的記錄方式標準化,因為這些事件最後會被放入事件存放區中以供查詢和檢視。 在微服務方法中,讓不同團隊在單一記錄格式上取得同意是一件非常重要的事。 需要有一致的方法可檢視整個應用程式中的診斷事件。

健康狀態與診斷不同。 健康狀態是微服務對其目前狀態採取之適當動作的報告。 使用升級與部署機制維護可用性是良好的範例。 雖然目前服務可能由於處理序損毀或重新開機而狀況不良,但服務可能仍會運作。 您所需要的最後一件事,就是藉由開始升級,讓情況更糟。 最好是先進行調查,或讓微服務有時間復原。 微服務的健康狀態事件能幫助我們做出明智的決定,並能確實幫助我們建立自我修復的服務。

在 Azure 上設計微服務的指導

請造訪 Azure 架構中心,以取得在 Azure 上建立微服務的指引。

Service Fabric 做為微服務平台

Azure Service Fabric 的出現,源自於 Microsoft 從提供盒裝產品 (通常是單體式) 轉換到提供服務。 建置和操作大型服務 (例如 Azure SQL Database、Azure Cosmos DB、圖形化 Service Fabric) 的經驗。 此平台已隨著越來越多的服務採用它而演化。 Service Fabric 不僅必須在 Azure 中執行,也必須在獨立式 Windows Server 部署中執行。

Service Fabric 的目標是解決建置和執行服務方面的艱難問題,以及有效率地利用基礎結構資源,讓團隊可以使用微服務方法來解決商務問題。

Service Fabric 透過提供下列項目,來協助您使用微服務方法建置應用程式:

  • 一個提供系統服務的平台 - 這些服務可進行部署、升級、偵測及重新啟動失敗的服務、探索服務、路由傳送訊息、管理狀態,以及監視健康情況。
  • 部署應用程式的能力 - 不論這些應用程式是在容器中執行,還是以處理序形式執行。 Service Fabric 是一個容器和處理序協調者。
  • 具生產力的程式設計 API,以協助您將應用程式建置成微服務:ASP.NET Core、Reliable Actors 及 Reliable Services。 例如,您可以取得健康情況和診斷資訊,或利用內建的高可用性。

Service Fabric 不會限制您建置服務的方式,您可以使用任何技術。不過,其會提供可讓您輕鬆建置微服務的內建程式設計 API。

將現有的應用程式移轉到 Service Fabric

Service Fabric 可讓您重複使用現有的程式碼,而這些程式碼可藉由新的微服務來進行現代化。 應用程式的現代化階段有五個,而您可以在任何階段開始和停止。 這些階段包括:

  1. 開始使用傳統單體式應用程式。
  2. 移轉。 使用容器或客體可執行檔來裝載 Service Fabric 中現有的程式碼。
  3. 現代化。 將新的微服務與現有的容器化程式碼一起新增。
  4. 創新。 根據需求將整合型應用程式分解成微服務。
  5. 將應用程式轉換成微服務。 轉換現有的整合型應用程式,或建立新的起步應用程式。

Migration to microservices

請記住,您可以 在任何階段開始和停止。 您不需要進行下一個階段。

讓我們看看這每一個階段的範例。

移轉
有兩個原因,許多公司都將現有的整合型應用程式遷移到容器中:

  • 降低成本,不論是透過合併和移除現有的硬體,或是透過以更高密度的方式執行應用程式。
  • 開發與作業之間的一致性部署合約。

成本降低很簡單。 在 Microsoft,許多現有的應用程式都是容器化的,因此節省了數百萬美元的費用。 一致性部署較難以評估,但同樣重要。 這表示開發人員可以選擇符合這些技術的技術,但作業只會接受單一方法來部署和管理應用程式。 它緩和了作業必須處理許多支援不同技術的複雜性,無需強制開發人員只能選擇特定技術的情況。 基本上,每個應用程式都會透過容器化成為獨立性部署映像。

許多組織都在此停止。 它們已經享有容器的好處,而且 Service Fabric 提供包含了部署、升級、版本設定、復原、健康情況監視等完整的管理體驗。

現代化
現代化是在現有的容器化程式碼之外,再加上新的服務。 如果您要撰寫新的程式碼,最好是決定順著微服務的路徑步步為營。 這可能是新增新的 REST API 端點,或是新的商務邏輯。 如此一來,您便開始了建置新微服務的流程,以及練習開發和部署這些微服務。

創新
微服務方式能容納持續變更的商務需求。 在此階段,您必須決定是否應該開始將單體式應用程式分割成不同服務,還是應該進行創新。 其中一個經典範例,就是當作為工作流程佇列的資料庫,變成處理上的瓶頸時。 隨著工作流程要求數目的增加,將需要分配工作來進行調整。 針對該應用程式無法進行調整或需要頻繁更新的部分,請將它分割為微服務並進行創新。

將應用程式轉換成微服務
在這個階段,您的應用程式完全由 (組成,或分割成) 微服務。 到目前為止,您已經進行了微服務旅程。 您可以從這裡開始,但是在沒有微服務平台來協助您的情況下執行此操作會是相當大的投資。

微服務適合我的應用程式嗎?

可能。 Microsoft 中越來越多團隊基於商業理由開始針對雲端進行建置,有許多團隊都了解到採用類似微服務的方法所帶來的優點。 例如,Bing 多年來一直使用微服務。 對於其他團隊而言,微服務方法很新穎。 團隊發現在他們的核心強項之外,還有需要解決的困難問題。 這就是為什麼 Service Fabric 受到重視而成為建置服務的最佳技術。

Service Fabric 的目標是降低建置微服務應用程式的複雜性,讓您不需要經歷許多耗費成本的重新設計工作。 從小規模開始、需要時調整、淘汰服務、加入新服務,並隨客戶使用情況而演化。 我們也知道,為了讓微服務更易於為大部分開發人員所接受,還有許多其他尚待解決的問題。 容器和動作專案程式設計模型是該方向的小步驟範例。 我們確定會出現更多創新,以簡化微服務方法。

下一步