微服務架構近年來成為軟體設計的主流趨勢,其核心概念是將大型應用程式拆分成多個小型、獨立佈署的服務。這樣的設計讓開發團隊能更專注於單一功能的開發與維護,同時也提升了系統的彈性、擴充套件性和可靠度。不同於傳統單體式架構,微服務架構允許每個服務獨立更新和佈署,無需重新構建整個應用程式,大幅縮短了開發週期並降低了風險。此外,微服務架構也更能適應雲原生環境,透過容器化技術和自動化佈署工具,可以更有效地管理和擴充套件服務。在服務間通訊方面,非同步通訊和發布/訂閱模式有效降低了服務之間的耦合度,提升了系統的容錯能力。API Gateway 作為單一入口點簡化了客戶端與服務之間的互動,同時也提供了負載平衡、身份驗證等功能。而 Service Registry 則負責管理微服務的地址資訊,讓服務發現更加便捷。這些技術的整合讓微服務架構更具實用價值,也為現代軟體開發帶來了新的可能性。
微服務架構的好處與應用
微服務架構的優勢
更新與維護成本
在微服務架構中,更新或新增功能(微服務)相較於單一巨石式應用程式來說,簡單許多。巨石式應用程式通常需要重建整個應用程式,而微服務只需更新或新增特定的微服務即可。這樣的設計不僅縮短了更新、構建、測試和佈署的時間,還減少了人為錯誤的風險。此外,微服務的測試和佈署過程通常比巨石式應用程式更短且更快速,甚至在某些情況下不需要停機。
擴充套件成本
微服務架構允許按需擴充套件特定的元件,而不需要擴充套件整個應用程式。這意味著你可以根據實際需求自動啟動或銷毀服務容器,從而節省硬體和軟體資源。這種靈活的擴充套件方式不僅提高了效率,還降低了營運成本。
上市時間
在微服務架構中,新增一個服務並上線通常比更新巨石式應用程式更快速。此外,微服務的模組化架構與容器技術結合,使得DevOps成為可能。DevOps提供了速度、穩定性、效能和協作四大要素,從而實作敏捷開發和快速上市。對於希望保持競爭優勢的組織來說,快速上市可能是轉向微服務架構最具吸引力的回報之一。
擴充套件比較
以下為擴充套件比較
graph TD; A[巨石式應用] --> B[啟動整個應使用案例項]; B --> C[耗費大量資源]; D[微服務] --> E[僅啟動需要的元件]; E --> F[節省資源並提高效率];
此圖示展示了巨石式應用和微服務在擴充套件方面的差異。巨石式應用需要啟動整個應使用案例項,耗費大量資源;而微服務則僅啟動需要的元件,從而節省資源並提高效率。
成本結構
以下為成本結構
graph TD; A[巨石式應用] --> B[負載平衡器]; B --> C[API閘道器]; C --> D[單一巨石式應用]; E[微服務] --> F[負載平衡器]; F --> G[Ticketing微服務]; F --> H[Search微服務]; F --> I[Catalog微服務];
此圖示展示了巨石式應用和微服務在成本結構上的差異。巨石式應用通常依賴單一的巨石式應用來處理所有請求,而微服務則透過多個獨立的微服務來處理不同的功能請求。
未來更新週期
在傳統的巨石式架構中,軟體應用有一個有限的平均壽命。當這個壽命結束時,組織通常會開始一個新的週期,這會帶來額外的初始成本。然而,微服務打破了這種迴圈概念。它們提供了靈活性,可以根據業務需求新增或移除微服務。此外,可以根據需求擴充套件或縮小系統規模,並替換過時技術中的特定微服務以最小化成本。
因此,由於其靈活性和模組化設計,轉向微服務架構將帶來顯著的長期成本文約。
內容解密:
- 更新與維護成本:強調了在巨石式應用中重建整個系統所帶來的人力及時間成本相對於只更新或新增單一功能(即:一個獨立運作之「MicroService」)之便利。
- 擴充套件成本:說明瞭只要有必要即可擴充或收縮特定元件之容器裝置,強調了針對需求運作之效能提升及資源節約。
- 上市時間:指出新增功能在「MicroService」中的便利性及與「DevOps」搭配之下達到敏捷開發及快速上市之優勢。
- 未來更新週期:強調了根據「MicroService」之靈活性與模組化設計可讓系統經常維持最高業界標準及達到降低長期維護費用之目的。
微服務之間的通訊
在微服務架構中,不同的服務之間需要進行通訊,以完成複雜的業務邏輯。這些通訊方式可以分為同步通訊和非同步通訊。同步通訊是指客戶端發出請求後,會等待另一個服務的回應,然後才繼續進行下一步工作。然而,這種方式存在一些問題:如果被呼叫的服務故障或錯誤,客戶端會被阻塞,無法繼續工作。這種情況下,系統的擴充套件性會變差,且無法充分發揮微服務架構的優勢。
因此,非同步通訊成為了一個更好的選擇。在非同步通訊中,客戶端發出請求後,不會等待回應,而是繼續進行其他工作。同時,客戶端會透過監聽執行緒來接收來自其他服務的回應。這樣做的好處是,即使被呼叫的微服務出現問題,也不會對客戶端產生影響,從而提高了系統的擴充套件性和鬆耦合性。
另一種常見的通訊方式是發布/訂閱模式(Publish/Subscribe)。在這種模式下,發布者將訊息發布到訊息匯流排(如Kafka)上。訂閱者則根據自身需求從訊息匯流排上訂閱感興趣的訊息並進行處理。處理完畢後,訂閱者可能會將結果再次發布到訊息匯流排上,這取決於所使用的訊息交換模式。
準備撰寫網路服務
在準備撰寫網路服務時,開發者需要決定以下三個關鍵問題:
協定選擇
在網路服務協定中,HTTP 是最常見且最可靠的選擇。它是同樣被網頁瀏覽器使用的協定,已經經歷了時間的考驗。HTTP 的主要優勢在於它非常輕量且根據簡單的請求/回應模型:客戶端形成並傳送 HTTP 請求,伺服器執行所需操作並傳回 HTTP 回應。
網路服務標準
有三個主要選擇:
- RESTful:廣泛接受且推薦使用。
- SOAP:較為臃腫,需要客戶端和伺服器端進行實作。
- GraphQL:開放協定用於構建和消費 RESTful API。
RESTful 根據 HTTP 請求和回應機制,比 SOAP 輕量許多。此外,RESTful 服務是無狀態且可快取的,這使得它們更快——對於支援移動裝置請求尤為重要。
訊息格式
常見且可接受的訊息格式包括 XML、RSS 和 JSON。其中 JSON 是許多開發者的最愛,因為它是根據文字且人類可讀的。此外,有許多函式庫可以輕鬆地將 JSON 轉換為物件及其反向轉換。由於 JSON 沒有過多語法負擔,JSON 資料比 XML 資料更小。這意味著處理速度更快,因為傳輸和接收訊息所需的頻寬更少。JSON 特別適合手持和移動裝置(如手機和平板電腦電腦),這些裝置儲存空間有限、計算能力輕量且頻寬需求低以傳輸訊息。
不同的人有不同的需求和偏好,所以本章節所提供的是建議。根據你自己的需求、效能要求及舒適度來做出選擇。
微服務維護
建立微服務之間的通訊之後,你需要保持它們更新並維護它們。廣泛應用的一句箴言“變化是唯一不變”也適用於你的軟體開發過程中。新功能要求總是伴隨著對現有功能進行調整或修改需求而來。這就是微服務架構中的複雜性之一。
以下是需要處理的一些問題:
- 支援現有客戶端實作:有時候你需要更新介面以修改微服務的核心功能。你必須確保微服務具有向後相容性因為其他的微服務可能正在使用這個已釋出介面進行通訊。
- 故障安全設計:如果被呼叫的網路服務異常關閉時可以透過超時來解決此問題。
- 監控:主動監控微服務以定期檢查其狀態或其他方法來監控其健康狀況。
- 排隊:在建立非同步網路服務時使用發布/訂閱方法來處理異常情況下提供穩定性。
發現服務
當你有一百甚至數千個微服務時會遇到什麼情況?可能你還需要為每個微服務提供多個網路服務甚至為同一個功能提供不同客戶端基礎上的網路服務——例如不同客戶端基礎上的網路服務。
在單一架構下不是一個問題因為客戶端只需要做一次呼叫即可完成所有工作,而背後還有應用程式可以解決剩餘問題。
然而在微服務架構下則會遇到兩大問題:
- 客戶端必須同時呼叫多個網路服務以達成之前單次呼叫就可以完成的一致性。
- 客戶端必須知道每個網路服務所在位置。
假設有一位使用者正在使用圖書館管理應用程式並想檢視自己的帳戶頁面:帳戶頁面顯示借閱歷史、推薦書籍、目前購物車內容、支付資訊及帳號設定等資訊。
如果該應用程式根據單一架構則當使用者點選「我的帳號」時系統後台會自動完成各項工作並查詢資料函式庫以顯示「我的帳號」頁面;對於手持裝置和移動裝置而言可能需要根據螢幕空間及計算能力來決定呼叫哪些 API 或哪些次序呼叫 API 來完成所需功能這增加了系統設計難度。
但在根據微服務架構之下則需要客戶端自己負責呼叫所有所需之微服務例如借閱歷史、支付資訊及帳號設定等資料;這樣做效率極低且容易造成系統僵化。
分析
因此在設計微服務架構時我們可以使用「Api Gateway」來充當代理伺服器來解決上述問題;藉由「Api Gateway」來統一管理所有外部 API 呼叫與內部 API 轉接並統計分析流量狀況達到安全性與效能最大化:
- API Gateway:集中管理所有外部 API 呼叫與內部 API 轉接並統計分析流量狀況達到安全性與效能最大化。
- Service Discovery:使用像是 Eureka 或 Consul 的工具來管理各個微服務地址以及健康狀態檢查達成高用性以及自動還原機制。
- Load Balancer:採用如 Ribbon 或 Nginx 的負載平衡技術將請求平均分配到不同的伺屬例項上達成避免單點故障並提升系統穩定性。
- Circuit Breaker:透過 Hystrix 或 Resilience4j 構建熔斷機制來避免某些不穩定介面對整體系統造成影響達到穩定執行。
- Logging and Monitoring:使用 ELK stack(Elasticsearch, Logstash, Kibana)或 Prometheus + Grafana 等工具進行日誌收集與監控分析達到及時排除故障與維護執行狀態。
此圖示
graph TD; A[Client] --> B[Api Gateway]; B --> C[Service Discovery]; C --> D[Service Instance]; D --> E[Load Balancer]; E --> F[Microservice Instance]; F --> G[Database];
小段落標題
圖示說明
此圖示展示了 Api Gateway 在微服務架構中的作用以及各個元件之間如何互動:
- 客戶端透過 Api Gateway 呼叫外部 API 或內部 API 轉接
- Api Gateway 集中管理所有請求並進行統計分析
- Service Discovery 用於管理各個微服務例項地址以及健康狀態檢查
- Load Balancer 用於將請求平均分配到不同的例項上
- Microservice Instance 提供實際業務邏輯並與資料函式庫互動
微服務架構中的發現服務
在微服務架構中,發現服務是確保系統可靠執行的關鍵元件之一。傳統的硬編碼方式無法應對動態變化的需求,例如將微服務進一步分割或合併。此外,客戶端需要知悉所有微服務的位置,這樣的設計顯然不夠靈活。因此,我們需要一個系統來作為客戶端和外部呼叫的整體入口點,同時還需要一個系統來儲存微服務的最新位置。
API Gateway
API Gateway 是解決上述問題的有效方法,它作為所有呼叫的入口點。其主要職責是接收客戶端請求、呼叫所需的微服務,並將微服務的聚合結果傳回給客戶端。這樣,客戶端只需要進行一次呼叫即可完成整個服務請求。這種模式帶來了多方面的優勢:
- 隱藏應用程式的內部複雜性,簡化客戶端程式碼。
- 提供更大的靈活性,可以根據需求隨時變更、合併、分割、新增或移除微服務。
- 減少客戶端與應用程式之間的往返次數,提高效率。
此外,API Gateway 還可以用於負載平衡、身份驗證、監控和管理。它可以為不同的客戶端(如網頁和手機)提供不同的 API,並且可以根據需要優先處理請求。
然而,API Gateway 的缺點是它可能成為單點故障和效能瓶頸。因此,必須進行有效的自動化組態和維護以確保其高效執行。例如,隨著微服務的修改、新增或刪除,API Gateway 必須保持最新狀態。從執行效能方面來看,彈性負載平衡器可以確保效能和可用性指標得到滿足。
API Gateway 在微服務架構中的角色
graph TD A[Client] --> B[API Gateway] B --> C[Microservice A] B --> D[Microservice B] B --> E[Microservice C] C --> F[Database A] D --> G[Database B] E --> H[Database C]
內容解密:
此圖示展示了 API Gateway 作為所有客戶端請求的入口點。當客戶端發出請求時,API Gateway 會呼叫所需的多個微服務(Microservice A、B 和 C),並將這些微服務傳回的結果進行聚合後送回給客戶端。每個微服務可能會連線到不同的資料函式庫(如 Database A、B 和 C),這樣可以將業務邏輯分散到不同的微服務中,提升系統的靈活性和可維護性。
Service Registry
在擁有數千個微服務的環境中,API Gateway 需要了解每個微服務的位置(如 IP 地址)才能正常工作。這就是 Service Registry 的作用所在。Service Registry 提供了一個包含所有微服務及其位置資訊的資料函式庫,並且可以在需要時查詢這些資訊。
每個微服務開發者都需要負責建立和維護 Service Registry。當一個微服務啟動時,它會自動向 Service Registry 註冊自己。當客戶端發出請求時,API Gateway 會查詢 Service Registry 以取得所需微服務的位置資訊,然後進行相應呼叫並聚合結果。
然而,這種設計仍然存在一些挑戰。例如,如果丟失了 Service Registry 的資料該怎麼辦?為瞭解決這個問題,我們可以使用一些開源工具如 Consul 和 SkyDNS。這些工具可以自動發現微服務並確保它們正常執行。Consul 是一款成熟的發現工具,可以使用自定義 DNS 名稱來存取微服務並儲存這些資訊到 Registry 中。此外,它還可以進行持續健康檢查以保持叢集健康。
Service Registry 的作用
graph TD A[Client] --> B[API Gateway] B --> C[Service Registry] C --> D[Microservice A] C --> E[Microservice B] D --> F[Database A] E --> G[Database B]
內容解密:
此圖示展示了 Service Registry 在整個流程中的角色。當 API Gateway 接收到客戶端請求時,它會向 Service Registry 查詢所需微服務(如 Microservice A 和 B)的位置資訊。然後 API Gateway 會根據這些位置資訊呼叫相應的微服務並聚合結果傳回給客戶端。
整合與擴充套件
讓我們透過一個簡單系統來看看如何將上述概念整合起來。
首先是一個簡單的根據微服務架構模型(如圖 3.1)。在此模型中,客戶端負責呼叫所有必要的微服務以完成使用者請求。
接下來新增一個 API Gateway(如圖 3.2),使其承擔所有業務邏輯並隱藏複雜性。這樣客戶端只需進行一次呼叫即可完成任務。
然後再新增一個 Service Registry(如圖 3.3),使得 API Gateway 能夠查詢所需微服務的位置資訊以完成請求處理。
最後一步是將系統擴充套件到更高階別(如圖 3.4)。為了滿足可擴充套件性要求,我們需要在必要時加入彈性負載平衡器以確保系統穩定執行。
在實際操作中,我們會在後續章節中進一步探討如何使用 Docker 來實作這些概念。
小段落標題:實際案例與應用
以某電子商務平台為例來說明這些概念在實際應用中的具體操作流程:
- Client Request: 使用者在電子商務平台上進行購物操作時發出請求。
- API Gateway: 請求被導向至 API Gateway。
- Service Query: API Gateway 查詢 Service Registry 得知需要呼叫哪些微服務及其位置。
- Microservices Execution: API Gateway 呼叫相關 micro-services(如 Inventory Service、Payment Service、Order Service)。
- Data Aggregation: 各 microservices 執行完畢後傳回結果給 API Gateway。
- Response Delivery: API Gateway 聚合結果傳回給 Client。
透過這樣設計能夠大幅提升系統之間互動效率及靈活度,同時也能更容易地對各部分進行擴充套件和維護。