當應用走向微服務,基礎設施層決定了你的服務能不能被可靠的部署、發現與彼此溝通。這層的模式大致分成兩塊:Deployment(如何部署)與Discovery(如何找到彼此)。下面用實務語言把圖中的重點一次講清楚。
基礎架構的部分與先前的應用程式基礎架構之間的差異一個是偏向容器或是虛擬機這種底層接近硬體的設施,一個是偏向 Middleware 的解決方案,在本篇章我們介紹的是「基礎架構模式」,這個更接近於底層。
Multiple services per host(同機多服務)
• 概念:一台主機上跑多個服務與應用程式。
• 優點:資源利用率高、啟服成本低。
• 風險:相互影響大、隔離性差、排查困難。
• 適用:開發/測試、小規模 PoC。不建議正式區長期使用。
這種情況常見於測試區的部署,因為客戶很多時候選用商用的 Kubernetes 平台,所以為了節省授權的費用,就會出現這種 Multiple service per host 的情況。對於某些 Kubernetes 運算資源不足的企業,這樣的部署模式也是節省費用的一種考量(雖然,原理上是不建議長期在正式區使用)。
Single service per host(單機單服務)
• 概念:一台主機只跑一個服務。
• 優點:隔離清楚、資源可控、除錯容易。
• 風險:資源浪費、維運碎片化。
• 適用:早期轉型或安全/合規要求嚴苛場景。
基本上,在微服務採用 Kubernetes 的時候比較少看到有獨立的服務佔據一整個 host 的情境。我想除非這個應用重要性夠高,且需要比較完整的運算資源來保護,不然我碰到的情境很少用者個模式來運作。
Service-per-VM / Service-per-Container(每 VM/每容器一服務)
• 概念:以 VM 或容器為單位承載單一服務。
• 優點:良好隔離、可彈性擴縮、與平台工具鏈整合成熟。
• 差異:VM 啟動慢、資源重;容器輕量、啟動快、密度高。
• 適用:容器優先為主流;特定合規或硬體相依改用 VM。
基本上,沒有人說微服務一定搭配「容器」,最早我們搭建的微服務系統也是在 VM 上建置,雖然可能不好做「自動擴容」這些事情,但其服務分拆的精神依然存在。
Service deployment platform(服務部署平台)
• 概念:以 Kubernetes/雲平台為代表,提供排程、擴容、滾動升級、探測等。
• 價值:把部署與運維標準化;讓團隊把時間花在業務上。
• 建議:落地 GitOps、Helm/ArgoCD,統一 CI/CD 與配置管理。
這段就是建議在微服務系統中應該建立自動化的整合與部署平台,屬於 CI/CD 落實的描述。
Sidecar(邊車)
• 概念:把橫切能力(mTLS、重試/熔斷、遙測)下放到同 Pod 的 Sidecar。
• 優點:業務程式零入侵、能力一致。
• 代價:資源開銷、網路跳數、排障更複雜。
• 適用:需要跨語言一致治理、對安全與流量控管有硬需求。
Sidecar 的模式是在原本服務旁邊放置一個應用程式來處理 mTLS、重試/熔斷、遙測等相關機制,但近年的實務經驗顯示這個模式太耗資源,所以有用 ambient 取代 sidecar 來實作 Service Mesh 的趨勢。
Service mesh(服務網格)
• 概念:以 Sidecar + 控制平面(如 Istio/Linkerd)提供流量治理、mTLS、金絲雀、熔斷、可觀測。
• 優點:策略集中化、與應用解耦。
• 代價:學習/維運成本高,錯配會全域受影響。
• 適用:多語言、多團隊、大規模場景;小團隊慎選、可先用輕量 Gateway/SDK。
Service registry(服務註冊中心)
• 概念:服務啟動時把自己的位址註冊進登錄中心(如 Eureka、Consul),供他人查找。
• 關鍵:健康探測、TTL、去註冊、版本/權重。
一家電商把 order-service、catalog-service、payment-service 跑在 Kubernetes 與裸機混合環境。服務啟動時向 Consul 註冊自己的位址與健康檢查端點資訊;當某節點滾動升級或自動擴縮時,新的節點自動去註冊確保可立刻被查到。order-service 呼叫 payment-service 前會先向 registry 查詢可用服務與其版本/權重,確保藍綠併存期間優先導向新版本。
Client-side discovery(用戶端發現)
• 流程:呼叫方向 registry 查詢→直接呼叫實例(本地做負載均衡)。
• 優點:少一跳、靈活。
• 代價:客戶端 SDK 要更新、語言多樣時治理成本高。
• 適用:內網服務間、語言栈一致時。
內網的 reporting-service 每晚要並行掃描多個 warehouse-service 。它先向 Consul 拉取 warehouse-service 的所有健康實例清單,使用本地演算法(如權重輪詢、就近可用區)直接打到實例,並在 SDK 內建重試/熔斷。由於所有服務都用 Java/Spring,同一套客戶端 SDK 易於推廣、維護成本可控。
行動 App 與合作夥伴都打到公司的 API Gateway(或雲端 LB)。Gateway 依路由把 /v1/orders/ 轉到 orders-bff。Gateway 與服務註冊中心整合,由它在伺服端查詢可用實例並做負載均衡、限流、驗證與觀測;對多樣化客戶端而言完全透明。當 orders-bff 自動擴縮或升級時,客戶端無需更新任何 SDK。
舊有 VM 叢集上有一批 .NET Framework 的 billing-service,無法依賴 Kubernetes Controller。每個服務實例啟動時會以程式碼呼叫 register() 註冊,並每 30 秒送心跳續租;若健康檢查失敗或進程關閉,會主動 deregister()。這讓拓撲能即時反映,避免報表或清算批次打到失效實例。
公司全面容器化,採 Kubernetes + Istio。不希望應用程式知道「註冊中心」這件事,於是用 控制器/Sidecar 將 Pod 的生命週期自動同步到 Service Registry(如 Consul-Connect 或 Istio 自身的服務目錄)。當 Pod 就緒探針 Ready 才會被註冊;若 Pod CrashLoop 或被驅逐,控制面會立刻從 registry 移除。應用完全零侵入,語言異質(Go、Node、Java)也能一致運作。
在微服務的基礎架構中,Microservice Architecture 的主要指引是「部署」與「服務發現」兩個主要概念。
在部署的部分,著要關乎到部署的環境以及部署的模式。服務發現則是微服務分散式架構得以運作的重點,不要假設微服務運作的環境一定依賴於 Kubernetes 或是容器平台,很多時候要讓企業內的應用都可以正常互動是需要支援不同環境下都能運作的模式。例如:服務發現可能透過 Consule 這種第三方的軟體可以同時讓 Kubernetes 內及外部的服務註冊的平台會是比較好的技術選項。
這也呼應 Sam Newman 在建構微服務一書中提及不要太早考慮 Kubernetes 的場景,讓我們的架構保持「彈性」課以適應各種不同的情境而作出改變,這才是面對 VUCA 時代應該具備的適應力。