Chuyển đến nội dung chính

第 6 課:服務間通訊 — 同步、非同步與事件驅動

同步(HTTP、gRPC)與非同步(訊息佇列、事件流)通訊。請求-回覆、發布-訂閱、事件通知模式。何時使用 RabbitMQ、Kafka、NATS。避免分發整體反模式。

🏗️ 建築 — 第 6 課 第 6 課:服務間通訊 — 同步、 異步和事件驅動

微服務與微前端系統設計-從基礎到生產

第 2 部分:設計微服務後端

亞洲開發網

簡介

微服務之間如何通訊決定了整個系統的耦合性、可靠性和性能。本文分析了通訊模式並指導如何為每個用例選擇正確的模式。

服務間通訊-同步、非同步和事件流


1. 同步通信

1.1 請求-回覆模式

┌──────────┐   HTTP/gRPC    ┌──────────┐
│  Order   │ ──────────────►│ Product  │
│  Service │◄────────────── │ Service  │
└──────────┘   Response     └──────────┘

Order Service gọi Product Service để validate product trước khi tạo order.
Phải đợi response → coupling tạm thời (temporal coupling).

優點:

  • 簡單、易懂、易調試
  • 立即回應
  • 明確錯誤處理(HTTP 狀態代碼)

缺點:

  • 時間耦合:呼叫者被阻止,直到收到回應
  • 級聯故障:如果產品服務故障 → 訂單服務也出現故障
  • 延遲隨著呼叫鏈中的每一跳而增加

1.2 最小化同步風險

  • 斷路器:當下游服務故障時斷開電路
  • 超時:設定合理的超時時間(不要太長)
  • 使用退避重試:使用指數退避重試
  • 後備:返回快取資料或預設回應
  • Bulkhead:隔離每個下游的連線池

2. 非同步通信

2.1 訊息佇列模式

┌──────────┐   Enqueue      ┌──────────┐   Dequeue     ┌──────────┐
│  Order   │ ──────────────►│  Queue   │──────────────►│  Email   │
│  Service │                │(RabbitMQ)│               │  Service │
└──────────┘                └──────────┘               └──────────┘

Fire-and-forget: Order Service gửi message, không đợi.
Email Service xử lý khi sẵn sàng (rate riêng).
Queue đảm bảo message không mất.

使用案例:

  • 任務分配(發送電子郵件、調整圖像大小)
  • 工作隊列(處理影片、產生報告)
  • 負載平衡(吸收流量峰值)

2.2 事件流/發布-訂閱模式

┌──────────┐                ┌──────────────┐
│  Order   │──publish──────►│    Kafka     │
│  Service │  OrderPlaced   │   Topic:     │
└──────────┘                │  orders      │
                            └──┬───┬───┬───┘
                               │   │   │
                    ┌──────────┘   │   └──────────┐
                    ▼              ▼              ▼
              ┌──────────┐  ┌──────────┐  ┌──────────┐
              │ Payment  │  │Inventory │  │  Email   │
              │ Service  │  │ Service  │  │  Service │
              └──────────┘  └──────────┘  └──────────┘

1 event → N consumers. Services không biết nhau → loose coupling.
Events được lưu trữ → có thể replay (event sourcing).

使用案例:

  • 領域事件(OrderPlaced、PaymentConfirmed)
  • 跨服務的資料複製
  • 事件溯源和審計跟踪
  • 即時分析

2.3 事件通知與事件攜帶狀態轉移

圖案活動包含什麼消費者需要什麼
活動通知僅限身分證明: {orderId: "123"}再次查詢來源服務
事件承載狀態完整資料: {orderId, items, total, ...}無需再次查詢

建議: 事件攜帶狀態傳輸有助於減少耦合(消費者不需要再次呼叫來源)。


3. 比較訊息代理

特色兔子MQ阿帕契·卡夫卡NATS
型號訊息佇列事件流/日誌發布/訂閱 + JetStream
訂購每個隊列每個分區每科
保留已消耗 → 已刪除可設定(幾天/永遠)JetStream:可設定
吞吐量~50K 訊息/秒~1M 訊息/秒~10M 訊息/秒
重播沒有是(基於偏移)捷流:是的
消費者群體是的是的捷流:是的
複雜性平均高(ZooKeeper/KRaft)低
最適合任務佇列、RPC事件流、採購雲端原生、輕量級

3.1 何時使用什麼?

RabbitMQ: Task queues (send email, process image)
          Request-Reply pattern (RPC over messages)
          Complex routing (exchanges, bindings)

Kafka:    Domain events (OrderPlaced, PaymentConfirmed)
          Event sourcing & CQRS
          Data pipeline & streaming analytics
          Audit trail (event log)

NATS:     Lightweight microservices communication
          Real-time messaging (chat, notifications)
          Cloud-native, Kubernetes-native
          Request-Reply + Pub/Sub combined

4. 混合方法(生產模式)

在實踐中,大多數系統使用兩者的組合:

┌─────────────────────────────────────────────────┐
│              E-Commerce Communication           │
├─────────────────────────────────────────────────┤
│ SYNCHRONOUS (REST/gRPC):                        │
│ • GET product details (query, cần response ngay)│
│ • Validate payment (command, cần kết quả)       │
│ • Search products (query, real-time)            │
├─────────────────────────────────────────────────┤
│ ASYNCHRONOUS (Kafka Events):                    │
│ • OrderPlaced → trigger Payment, Inventory      │
│ • PaymentConfirmed → trigger Shipping           │
│ • UserRegistered → trigger Welcome Email        │
│ • ProductUpdated → update Search Index          │
└─────────────────────────────────────────────────┘

總結

圖案何時使用權衡
同步(REST/gRPC)需要立即回复,查詢資料緊密耦合,級聯失效
非同步佇列任務分配、負載平衡最終一致性
非同步事件領域事件、資料同步複雜,偵錯困難
混合製作推薦需要管理兩者

下一篇文章: 第 7 課:每個服務的資料庫和多語言持久性