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

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 課:每個服務的資料庫和多語言持久性