This repository has been archived on 2026-05-24. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files

205 lines
6.7 KiB
Markdown
Raw Permalink Normal View History

2026-05-17 22:00:24 +08:00
---
tags: [microservice, rpc, rest, grpc, message-queue, event-driven]
create time: 2026-05-05
---
# 服务间通信
## 概述
微服务之间如何通信,是架构设计的核心决策之一。选错了通信方式,后面会带来一系列问题:耦合度太高、性能瓶颈、或者运维复杂度爆炸。
## RPC vs RESTful API
### 对比分析
| 维度 | REST over HTTP/JSON | gRPC (HTTP/2) | GraphQL |
|------|---------------------|---------------|---------|
| **性能** | 序列化开销大 | Protocol Buffers,二进制高效 | 中等(JSON) |
| **人类可读** | URL + JSON 直观 | 需要 Proto 定义辅助理解 | 查询语言自描述 |
| **语言兼容性** | 广泛,任何能发 HTTP 的语言都能用 | 需要代码生成 | 需客户端 SDK |
| **缓存** | 天然支持 HTTP 缓存 | 不支持(HTTP/2 多路复用替代) | 可设计缓存层 |
| **版本管理** | URL 路径 (/v1/, /v2/) | Proto 文件向前兼容 | Schema 演进工具 |
| **适用场景** | 对外 API、跨团队/跨组织调用 | 内部服务间高频强类型调用 | 前端聚合查询、移动端 |
```mermaid
graph TB
subgraph "何时选什么?"
D{"你的场景是?"}
D -->|"对外暴露 API"| REST["REST over HTTP"]
D -->|"内部服务高频调用"| GRPC["gRPC"]
D -->|"前端/移动端复杂查询"| GraphQL["GraphQL"]
D -->|"异步解耦通知"| MQ["消息队列"]
end
```
### 混合通信模式(推荐)
实际工程中很少单一选型。**最佳实践是混合使用**:
```mermaid
sequenceDiagram
participant C as 客户端
participant GW as API Gateway
participant O as Order Service
note over C,O: 外部请求 — 用 REST/gRPC
C->>GW: POST /orders (HTTP/JSON)
GW->>O: CreateOrder (gRPC)
note over O,O: 内部处理 — 同步 + 异步组合
O->>O: 创建订单记录 (本地事务)
O-->>GW: {orderId: "ORD-001"}
GW-->>C: 200 OK
O->>O: Publish OrderCreated Event (MQ)
Note right of O: 通知类场景异步处理
```
## 同步通信
### gRPC 协议详解
gRPC 基于 Protocol Buffers(Proto3),利用 HTTP/2 的多路复用特性,非常适合高性能的内部服务间调用。
> [!tip] 深入阅读
> [[06-gRPC]] — gRPC 深度指南,涵盖 Proto 进阶、流式调用、Interceptor、连接管理、生产最佳实践。
```go
// proto/order/v1/order.proto
syntax = "proto3";
package order.v1;
service OrderService {
rpc CreateOrder(CreateOrderRequest) returns (CreateOrderResponse);
rpc GetOrder(GetOrderRequest) returns (Order);
rpc StreamOrders(StreamRequest) returns (stream Order); // 服务端流
}
message CreateOrderRequest {
string user_id = 1;
repeated Item items = 2;
float total = 3;
}
message Item {
string product_id = 1;
int32 quantity = 2;
}
enum OrderStatus {
UNKNOWN = 0;
PENDING = 1;
PAID = 2;
SHIPPED = 3;
CANCELLED = 4;
}
```
**Proto3 注意事项**:
- 字段编号(`= 1`, `= 2`)不能重编——破坏向后兼容
- 新增字段标记为 `optional` 时 Proto3 才能区分"未设置"和"默认值"
- `repeated` 字段空数组不会省略,需要特殊处理
### RESTful API 设计规范
```
GET /api/v1/orders → 获取订单列表
POST /api/v1/orders → 创建订单
GET /api/v1/orders/{id} → 获取订单详情
PUT /api/v1/orders/{id} → 更新订单(全量替换)
PATCH /api/v1/orders/{id} → 部分更新
DELETE /api/v1/orders/{id} → 删除订单
```
**核心原则**:
- **资源名词化**:URL 用名词复数,不用动词
- **无状态**:每个请求携带完整上下文(通过 Header 传 Token)
- **统一接口**:用标准 HTTP Method + Status Code 表达语义
## 异步通信
### 事件驱动架构
> [!question] 关键时刻的判断
> 用户点击"提交订单"后,系统要做:① 创建订单记录 ② 扣减库存 ③ 扣款 ④ 发送短信通知。哪些步骤必须同步完成?哪些可以异步处理?为什么?
**答案**:①~③需要立即得到结果或保证一致性,走同步流程;④纯粹的通知类场景完全异步,用消息队列解耦。即使扣款失败,短信也没必要发出。
```mermaid
graph LR
A["订单创建"] --> B{"是否需要同步响应?"}
B -->|"是"| Sync["同步 RPC 链"]
B -->|"否"| Async["异步 MQ 事件"]
Sync --> Stock["查库存 (RPC)"]
Stock --> Pay["支付 (RPC)"]
Async --> SMS["发短信 (Event)"]
Async --> Points["加积分 (Event)"]
Async --> Email["发确认邮件 (Event)"]
```
### 消息队列选型
| 方案 | 吞吐量 | 延迟 | 可靠性 | 特色能力 |
|------|--------|------|--------|---------|
| **RocketMQ** | 极高 (百万级) | 毫秒级 | 事务消息支持 | 阿里出品,国内首选 |
| **Kafka** | 最高 (千万级) | 秒级 | 持久化 | 大数据生态集成 |
| **RabbitMQ** | 中等 (十万级) | 亚毫秒 | 高 | 灵活的路由模型 |
| **Pulsar** | 高 | 毫秒级 | 高 | 存储计算分离 |
### 发布订阅 vs 点对点
```mermaid
graph TB
Publisher[生产者] --> Broker[(MQ Broker)]
Broker --> Sub1["消费者组 A<br/>Topic: order-events"]
Broker --> Sub2["消费者组 B<br/>Topic: order-events"]
Broker --> Sub3["消费者组 C<br/>Topic: order-events"]
style Sub1 fill:#cfe2f3
style Sub2 fill:#d9e2f3
style Sub3 fill:#e2d9f3
```
- **发布订阅 (Pub/Sub)**:一个消息被多个消费组分别消费,每个组内只有一个实例收到
- **点对点 (Queue)**:一条消息只被一个消费者处理
## 同步与异步的组合拳
```mermaid
sequenceDiagram
participant Client
participant Gateway
participant Order
participant MQ
participant Notify
participant Analytics
Client->>Gateway: 下单请求
Gateway->>Order: 创建订单
Order->>Order: 写库 + 出消息(事务)
Order-->>Gateway: 返回 orderId
Gateway-->>Client: 202 Accepted ⚡
Note over MQ: 异步后续处理
MQ->>Notify: 发送通知
MQ->>Analytics: 数据统计
Note right of Client: 用户体验好:<br/>主流程快速响应<br/>非关键任务后台处理
```
> [!keypoint] 关键洞察
> - 同步链路:**gRPC 直连**,延迟低,适合核心事务链
> - 异步链路:**消息队列**,解耦非关键路径,即使失败也不影响主干
> - 核心原则:**同步保性能,异步保解耦**
## 关联笔记
- [[02-服务治理/01-API网关]] — API Gateway 负责协议转换
- [[03-数据一致性/02-分布式事务]] — 消息投递的一致性保障
- [[05-部署运维/02-Kubernetes]] — Sidecar 代理透明拦截通信流量