vault backup: 2026-05-17 22:00:24
This commit is contained in:
@@ -0,0 +1,204 @@
|
||||
---
|
||||
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 代理透明拦截通信流量
|
||||
Reference in New Issue
Block a user