共计 1498 个字符,预计需要花费 4 分钟才能阅读完成。
背景痛点
在微服务架构中,服务间通信的幂等性问题尤为突出。当网络抖动、客户端重试或消息队列重复投递时,非幂等接口会导致:

- 支付系统重复扣款
- 库存服务超卖
- 订单状态机混乱
某电商平台曾因未处理幂等问题,在促销期间产生 1200 万元的资金损失。这警醒我们:幂等不是可选项,而是分布式系统的生存底线。
技术方案对比
常见的幂等控制方案各有优劣:
- Token 机制
- 优点:实现简单
-
缺点:需要预请求,吞吐量低(约 800QPS)
-
DB 唯一索引
- 优点:强一致性保证
-
缺点:高并发下成为性能瓶颈
-
Skill 技术方案
- 综合优势:
- 万级 QPS 支持
- 无需预请求
- 业务无侵入
核心实现
全局唯一 RequestID 生成
// 雪花算法变体:机房 ID(3bit) + 机器 ID(7bit) + 毫秒序列(10bit)
public class RequestIdGenerator {
private static final int DATA_CENTER_BITS = 3;
private static final int WORKER_BITS = 7;
public String generate() {long timestamp = System.currentTimeMillis();
long sequence = Redis.incr("seq:" + timestamp) % 1024;
return String.format("%d-%d-%d",
timestamp,
(dataCenterId << WORKER_BITS) | workerId,
sequence);
}
}
分布式锁实现
-- KEYS[1]: 锁 key ARGV[1]:requestId ARGV[2]: 超时 ms
if redis.call("setnx", KEYS[1], ARGV[1]) == 1 then
redis.call("pexpire", KEYS[1], ARGV[2])
return 1
else
local current = redis.call("get", KEYS[1])
if current == ARGV[1] then
redis.call("pexpire", KEYS[1], ARGV[2])
return 1
end
end
return 0
状态机防护
class OrderStateMachine:
def __init__(self):
self.state = "created"
def transition(self, new_state):
transitions = {"created": ["paid", "canceled"],
"paid": ["shipped", "refunded"]
}
if new_state not in transitions.get(self.state, []):
raise IllegalStateException(f"Cannot change from {self.state} to {new_state}")
self.state = new_state
性能优化
压测数据对比(单节点 Redis)
| QPS | 平均响应时间 | 99 分位 |
|---|---|---|
| 5k | 12ms | 28ms |
| 10k | 19ms | 47ms |
| 20k | 35ms | 82ms |
锁粒度优化
- 订单类业务:按 orderId 分段(如尾号 mod 16)
- 用户类业务:按 userId 哈希分片
避坑指南
- 时钟漂移
- 所有节点强制使用 NTP 同步
-
本地时钟偏差超过 100ms 触发告警
-
锁超时公式
超时时间 = 平均业务处理时间 × 3 + 网络延迟缓冲区
代码规范要点
- Java 方法注释必须包含
@throws说明 - Python 需通过
mypy类型检查 - Redis 操作必须带 TTL(防死锁)
思考题
跨地域部署时如何保证幂等?
提示方向:
– 考虑全局时钟服务(如 TrueTime API)
– 评估 CRDT 数据结构适用性
– 权衡最终一致性边界
正文完
