Microservices & Monolithic Architecture

前言

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

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

Microservices架構如下圖:

每個服務都有他們專屬的DB,而這些服務不需要都用同一種語言去編寫,可以是不同語言,最終只需要透過Protobuf去互相調用即可

Microservices vs Monolithic Architecture

微服務架構(Microservices)與單體架構(Monolithic Architecture)的優缺點比較

特性 微服務架構 單體架構
開發複雜性 較高,需要管理多個服務的交互 較低,所有功能集中在一個應用中
技術棧靈活性 高,不同微服務可以使用不同的技術棧 低,整個應用通常使用單一技術棧
部署 獨立部署,單一服務的更新不會影響其他服務 整體部署,任何一個小改動都需要重新部署整個應用
擴展性 高,可以根據需求獨立擴展特定服務 低至中,擴展通常意味著擴展整個應用
容錯性 高,一個服務的失敗不會導致整個應用失敗 低,任何一個部分的失敗可能影響整個應用
開發和維護成本 較高,需要額外的管理和協調 較低,所有代碼在同一處管理
資料一致性 挑戰較大,需要管理跨服務的資料一致性 較容易實現,因為所有資料處理在同一應用內
啟動時間 快,單個微服務啟動時間短 慢,隨著應用規模增加,啟動時間可能變長
測試 複雜,需要考慮服務間的交互和集成測試 相對簡單,因為所有功能都在一個環境中
團隊協作 促進小團隊獨立工作,提高敏捷性 需要更大的團隊協作,可能導致溝通成本增加

各個服務間如何互相溝通?

由於每個服務都是獨立的,那服務之間該如何互相溝通?假設一個電商網站中主要有Customer, Products, Shopping,三種獨立的服務,但Products需要依賴於Customer服務的資料,該怎麼辦?

  1. 直接服務間調用

    • 同步調用
      在Products服務中透過HTTP、gRPC等通訊協議,直接對customer服務發送請求調用資料。
    • 亦步調用:
      使用消息隊列(如RabbitMQ、Kafka等)實現異步通訊,products服務發布消息到隊列,customer服務訂閱相應的消息進行處理,並將結果通過回調或再次發布消息的方式回傳。
      這種方式適用於不需要即時響應的場景,能有效分散高峰流量。
  2. 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}`)
      })
  3. 共享資料庫

    • 雖然在微服務架構中提倡每個服務都擁有自己的資料庫,但在某些情況下,服務間也可以通過共享資料庫的方式來達成資料通訊,但要注意資料的一致性與隔離性,避免產生緊耦合。

總結

微服務雖然好處多多,但維護以及資料一致性上還是有些挑戰,對於擴展大型應用就很適合使用微服務,相對的,在開發小型專案或是初期階段,還是選擇單體式架構較容易些。也因此,在開發專案前可以事先考慮長遠因素,比如維護成本、系統的復雜度、以及團隊的技術能力等,再選擇適合的架構比較好。
此篇文章僅記錄筆者蒐集資料彙整結果,若有任何錯誤歡迎指教,萬分感謝。

Reference

https://ithelp.ithome.com.tw/articles/10228461