第7章:可靠性(API Reliability)
一、导读
1.1 本章学习目标
第7章讲解 API 的可靠性设计——幂等性、重试、超时、错误处理。
本章的核心学习目标包括:
- 理解幂等性的重要性
- 掌握重试策略的设计
- 学会设计超时和错误处理
1.2 为什么本章如此重要
网络不可靠——请求可能超时、重复、丢失。API 必须能处理这些情况,保证数据一致性和用户体验。
1.3 核心问题引导
什么是幂等性?为什么它很重要?
重试策略应该如何设计?
超时时间如何确定?
错误响应应该包含什么信息?
二、核心概念详解
2.1 幂等性
幂等性:多次执行与一次执行效果相同
HTTP 方法的幂等性:
- GET:幂等(读取不改变状态)
- PUT:幂等(替换为相同状态)
- DELETE:幂等(删除已删除的资源无影响)
- POST:非幂等(每次创建新资源)
- PATCH:通常幂等
实现幂等性:
POST /api/v1/payments
Idempotency-Key: req_abc123 // 客户端提供的幂等键
// 服务器用幂等键去重
// 相同幂等键的请求返回相同结果2.2 重试策略
客户端重试策略:
1. 可重试的错误:
- 5xx 服务器错误
- 网络超时
- 429 限流
2. 不可重试的错误:
- 4xx 客户端错误(除了 429)
- 非幂等操作的请求已发送
3. 退避策略:
- 指数退避:1s, 2s, 4s, 8s...
- 加随机抖动:避免雷群效应
- 最大重试次数:3-5 次
4. 幂等键:
- 非幂等操作必须使用幂等键
- 确保重试安全2.3 超时设计
超时层次:
1. 连接超时:建立连接的时间(5-10s)
2. 读取超时:等待响应的时间(根据操作类型)
- 简单查询:5-10s
- 列表操作:15-30s
- 长运行操作:使用异步模式
3. 服务端超时:
- 设置请求处理的最大时间
- 超时返回 503 或 504
// 客户端配置
HttpClient client = HttpClient.builder()
.connectTimeout(Duration.ofSeconds(5))
.readTimeout(Duration.ofSeconds(30))
.build();2.4 错误处理
错误响应设计:
{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Too many requests",
"details": [
{
"type": "quota",
"limit": 100,
"remaining": 0,
"resetAt": "2024-01-01T01:00:00Z"
}
],
"requestId": "req_abc123",
"documentationUrl": "https://docs.example.com/errors/rate-limit"
}
}
// 标准错误码
RATE_LIMIT_EXCEEDED // 429
INVALID_ARGUMENT // 400
NOT_FOUND // 404
ALREADY_EXISTS // 409
PERMISSION_DENIED // 403
UNAUTHENTICATED // 401
INTERNAL // 500
UNAVAILABLE // 503
DEADLINE_EXCEEDED // 504三、实战案例
3.1 案例一:幂等支付 API
POST /api/v1/payments
Idempotency-Key: pay_20240101_001
Content-Type: application/json
{
"amount": 99.99,
"currency": "USD",
"customerId": "cust_123"
}
// 第一次请求
→ 201 Created
{
"id": "pay_456",
"status": "COMPLETED",
"amount": 99.99
}
// 重试(相同幂等键)
POST /api/v1/payments
Idempotency-Key: pay_20240101_001
→ 201 Created(返回相同结果)
{
"id": "pay_456",
"status": "COMPLETED",
"amount": 99.99
}四、本章小结
幂等性:多次执行与一次执行效果相同。
重试策略:指数退避 + 随机抖动 + 幂等键。
超时设计:连接超时、读取超时、服务端超时。
错误处理:标准错误码、详细信息、文档链接。
五、思考与练习
如何为非幂等的 POST 操作实现幂等性?
设计一个完整的重试策略。
如何确定 API 的超时时间?