1. 與單體架構 (Monolithic Architecture) 的對比 🏰➡️🧱
為了更好地理解微服務,我們先來對比一下傳統的 單體架構 (Monolithic Architecture):
- 單體架構 (Monolithic Architecture):
- 比喻: 就像一個巨大的、單一的城堡 🏰。所有功能(使用者管理、產品目錄、購物車、支付等)都緊密地耦合在一起,運行在一個單一的程式碼庫中,通常部署在一個單一的伺服器或叢集上。
- 優點: 初期開發簡單、部署相對容易(只需部署一個大應用程式)。
- 缺點:
- 擴展困難: 即使只有一個小功能需要更多資源,也必須擴展整個應用程式,造成資源浪費。
- 開發效率低: 程式碼庫龐大,團隊協作效率可能降低,新成員入門困難。
- 部署速度慢: 任何小改動都需要重新建構和部署整個應用程式。
- 技術鎖定: 一旦選定技術棧,很難在不同功能模組中使用其他技術。
- 單點故障風險: 某個小組件出問題,可能導致整個應用程式崩潰。
- 微服務架構 (Microservices Architecture):
- 比喻: 就像一個由許多獨立的樂高積木 🧱 組成的複雜城市。每個積木(服務)代表一個特定的業務功能,它們獨立運行,可以獨立開發、部署和擴展。這些服務之間透過輕量級的通訊機制(通常是 API)互相協作。
- 優點:
- 獨立部署與擴展: 每個服務可以獨立部署和擴展。例如,如果使用者服務負載高,你只需擴展使用者服務,而不影響其他服務。
- 技術多樣性 (Polyglot Persistence/Programming): 每個服務可以根據自身需求選擇最適合的程式語言、資料庫和技術棧。例如,產品服務可能用 Java 和關聯式資料庫,而日誌服務可能用 Python 和 NoSQL 資料庫。
- 開發效率高: 小型團隊可以專注於開發和維護一個小服務,程式碼庫小,新成員入門快。
- 彈性與韌性 (Resilience): 一個服務的故障不會直接導致整個應用程式崩潰。如果使用者服務掛了,其他服務(如產品瀏覽)可能仍然可以運作。
- 易於理解和維護: 每個服務的程式碼量較小,邏輯更清晰。
- 加速交付 (Fast Delivery): 可以頻繁地部署獨立的服務,實現 CI/CD。
- 缺點:
- 分散式系統複雜性: 管理多個獨立服務帶來的複雜性(服務發現、負載平衡、分散式事務、日誌、監控等)。
- 服務間通訊: 服務之間的通訊(通常透過網路)會引入延遲和潛在的故障點。
- 資料一致性挑戰: 服務擁有自己的資料庫,如何在多個服務之間保持資料一致性是一個挑戰(例如,分佈式事務)。
- 運維挑戰: 部署、監控和故障排除多個服務的複雜性增加,需要強大的自動化工具和 DevOps 能力。
- 測試複雜性: 測試一個由多個微服務組成的系統比測試單體應用更複雜。
2. 微服務的關鍵概念與技術 🔗
- 服務發現 (Service Discovery):
- 比喻: 想像一個電話簿或「黃頁」。當一個服務需要呼叫另一個服務時,它需要知道對方的網路位址。服務發現機制就是幫助服務找到彼此的地址。
- 功能: 允許微服務動態地註冊自己,並發現其他服務的網絡位置。
- 常見工具: Eureka, Consul, Zookeeper, Kubernetes 內建的服務發現。
- API Gateway (API 閘道):
- 比喻: 就像一個城市的「海關」或「前台」。所有來自外部(用戶端、其他系統)的請求都先通過 API Gateway,然後由它將請求路由到正確的後端微服務。
- 功能: 路由請求、身份驗證、授權、速率限制、日誌記錄、監控、快取等。
- 重要性: 作為外部世界與內部微服務之間的唯一入口,簡化了客戶端與微服務的交互,並提供統一的安全和管理層。
- 容器化 (Containerization) 與容器編排 (Container Orchestration):
- 容器 (Docker): 應用程式以容器的形式打包,確保每個服務及其依賴項在不同環境中的一致性運行。
- 容器編排 (Kubernetes): 這是管理和部署大量微服務的最佳工具。Kubernetes 能夠自動化微服務的部署、擴展、自我修復、服務發現和負載平衡。兩者是微服務架構的基石。
- 分佈式日誌 (Distributed Logging) 與監控 (Monitoring):
- 挑戰: 由於服務分散在多個伺服器上,傳統的日誌和監控方式不再適用。
- 解決方案: 需要集中化的日誌收集與分析系統(如 ELK Stack, Splunk)和分佈式監控系統(如 Prometheus, Grafana),以便追蹤跨服務的請求流和發現問題。
- 資料管理與事務:
- 每個服務擁有自己的資料庫 (Database per Service): 這是微服務的核心原則之一,每個服務應該獨立擁有和管理自己的資料。
- 分佈式事務 (Distributed Transactions) / 最終一致性 (Eventual Consistency): 在跨多個服務的複雜業務操作中,如何確保資料的一致性是一個挑戰。通常會採用「最終一致性」模型(例如透過訊息佇列和事件驅動架構)來避免傳統分佈式事務的複雜性。
- CI/CD (持續整合/持續部署):
- 微服務架構非常適合 CI/CD。每個服務可以獨立地進行建構、測試和部署,大大加快了迭代速度。
3. 微服務的應用場景 💡
- 大型複雜應用: 當應用程式規模龐大且功能眾多時,微服務可以將其拆分為可管理的小塊。
- 高頻率部署: 需要快速、頻繁地發布新功能和更新的應用。
- 需要技術多樣性: 不同的功能模組需要使用不同的技術棧時。
- 分佈式團隊: 允許不同團隊獨立開發和部署各自的服務。
- 雲原生應用: 在雲端環境中運行,充分利用雲端的彈性和可擴展性。