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
all-in-kingsoft/hhs/MS/02-服务治理/05-服务间通信.md
T
2026-05-17 22:00:24 +08:00

205 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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 代理透明拦截通信流量