Microservices & Monolithic Architecture
前言
我們以往都是透過單體式架構(Monolithic)去處理各種服務,且每個服務可能都依賴於同一個database,在部署上也只打包成一個名為”backend”的container,如下圖

但微服務不一樣的點在於,他是將每個服務獨立成自己的伺服器,以及配置他們專用的資料庫。
Microservices架構如下圖:

每個服務都有他們專屬的DB,而這些服務不需要都用同一種語言去編寫,可以是不同語言,最終只需要透過Protobuf去互相調用即可
Microservices vs Monolithic Architecture
微服務架構(Microservices)與單體架構(Monolithic Architecture)的優缺點比較
| 特性 | 微服務架構 | 單體架構 |
|---|---|---|
| 開發複雜性 | 較高,需要管理多個服務的交互 | 較低,所有功能集中在一個應用中 |
| 技術棧靈活性 | 高,不同微服務可以使用不同的技術棧 | 低,整個應用通常使用單一技術棧 |
| 部署 | 獨立部署,單一服務的更新不會影響其他服務 | 整體部署,任何一個小改動都需要重新部署整個應用 |
| 擴展性 | 高,可以根據需求獨立擴展特定服務 | 低至中,擴展通常意味著擴展整個應用 |
| 容錯性 | 高,一個服務的失敗不會導致整個應用失敗 | 低,任何一個部分的失敗可能影響整個應用 |
| 開發和維護成本 | 較高,需要額外的管理和協調 | 較低,所有代碼在同一處管理 |
| 資料一致性 | 挑戰較大,需要管理跨服務的資料一致性 | 較容易實現,因為所有資料處理在同一應用內 |
| 啟動時間 | 快,單個微服務啟動時間短 | 慢,隨著應用規模增加,啟動時間可能變長 |
| 測試 | 複雜,需要考慮服務間的交互和集成測試 | 相對簡單,因為所有功能都在一個環境中 |
| 團隊協作 | 促進小團隊獨立工作,提高敏捷性 | 需要更大的團隊協作,可能導致溝通成本增加 |
各個服務間如何互相溝通?
由於每個服務都是獨立的,那服務之間該如何互相溝通?假設一個電商網站中主要有Customer, Products, Shopping,三種獨立的服務,但Products需要依賴於Customer服務的資料,該怎麼辦?
直接服務間調用:
- 同步調用:
在Products服務中透過HTTP、gRPC等通訊協議,直接對customer服務發送請求調用資料。 - 亦步調用:
使用消息隊列(如RabbitMQ、Kafka等)實現異步通訊,products服務發布消息到隊列,customer服務訂閱相應的消息進行處理,並將結果通過回調或再次發布消息的方式回傳。
這種方式適用於不需要即時響應的場景,能有效分散高峰流量。
- 同步調用:
API網關 (Gateway)
使用API gateway作為服務間的中介,所有外部請求都會先經過API gateway,並透過proxy將請求導向相應的服務。
當product服務需要customer服務的資料時,可以透過API gateway轉發請求。這種方式可以在 API 網關層面統一處理認證、授權、監控等跨服務的共通關切。
透過gateway管理請求,發送到不同服務
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19//API Gateway
const express = require('express')
const cors = require('cors')
const proxy = require('express-http-proxy')
const app = express()
const PORT = 8000
app.use(cors())
app.use(express.json())
app.use('/customer', proxy('http://localhost:8001'))
app.use('/shopping', proxy('http://localhost:8003'))
app.use('/', proxy('http://localhost:8002')) // products
app.listen(PORT, () => {
console.log(`Gateway is running on http://localhost:${PORT}`)
})
共享資料庫
- 雖然在微服務架構中提倡每個服務都擁有自己的資料庫,但在某些情況下,服務間也可以通過共享資料庫的方式來達成資料通訊,但要注意資料的一致性與隔離性,避免產生緊耦合。
總結
微服務雖然好處多多,但維護以及資料一致性上還是有些挑戰,對於擴展大型應用就很適合使用微服務,相對的,在開發小型專案或是初期階段,還是選擇單體式架構較容易些。也因此,在開發專案前可以事先考慮長遠因素,比如維護成本、系統的復雜度、以及團隊的技術能力等,再選擇適合的架構比較好。
此篇文章僅記錄筆者蒐集資料彙整結果,若有任何錯誤歡迎指教,萬分感謝。