📌 引子:从“MAX+1”走向专业编号中心
在上一篇文章中,我们讲到一个看似不起眼的“单据编号”字段,在高并发场景下,居然成了系统并发能力的最大瓶颈。
许多企业的系统初期都简单使用:
-
数据库
MAX+1
查询; -
或者基于数据库的自增主键;
-
有些稍微优化一点的,使用 Redis 的
INCR
;
这些方案虽然容易实现,但在并发激增、服务拆分、租户膨胀的现实场景中,稳定性、可扩展性、安全性都严重不足。
本文将正式进入架构层面,拆解一个高可用、高吞吐、强隔离的统一编号中心设计方案,并结合实战经验提供优化建议。
🎯 编号中心的设计目标
设计一个统一编号服务中心,必须满足以下几个核心目标:
目标 | 描述 |
---|---|
高并发性能 | 支持每秒万级别编号生成请求 |
跨服务可调用 | 可被订单、发票、出库、结算等多个系统统一调用 |
编号规则灵活 | 支持按租户、按业务、按年份等维度定义前缀、序列等规则 |
多租户隔离 | 避免不同租户使用冲突编号段 |
可观察、可监控 | 编号池耗尽预警、QPS/RT 监控 |
容灾与持久化 | 服务宕机后不能丢号,须支持断点续号或持久化 |
🧱 架构设计总览
我们将整个编号中心拆分为以下关键组件:
1. 编号管理配置中心(编号策略管理)
-
管理每类编号的规则(如:订单、退货、支付等)
-
支持配置前缀(例如:ORD2025)、格式、每日清零、按租户分段等
2. 编号分发服务(ID分配核心服务)
-
接收请求并从缓存号段中分发编号
-
实现基于本地内存 + 持久化号段预分配的双层策略
3. 编号号段持久化存储(数据库层)
-
记录各业务编号的当前最大值、已分配号段等状态
-
支持加锁/乐观锁机制保障并发安全
4. 可选:雪花算法服务(Snowflake)
-
用于不关心“连续性”的唯一 ID 生成(如日志ID、TraceID)
🧩 常用编号生成方案对比
方案 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
MAX+1 | 实现简单 | 严重锁表,易冲突 | 非并发系统 |
DB自增 | 保证唯一 | 不支持多表共享 | 单体系统 |
Redis Incr | 高性能 | 宕机易丢失 | 非强一致要求场景 |
号段缓存(本地+DB) | 高并发、低延迟、持久化 | 实现稍复杂 | 推荐用于订单、出库单等业务编号 |
雪花算法 | 高性能、全局唯一 | 不支持规则定制 | 仅用于唯一性场景 |
🔧 编号中心核心算法:号段缓存策略
流程简介:
-
后台任务定期预加载号段(例如:订单编号 100000~100999)
-
服务调用时从本地缓存中取出并组装编号
-
当前缓存段快用完时,提前异步加载下一段号段
-
使用数据库版本号(
version
)或乐观锁更新新号段,确保并发安全
优点:
-
减少数据库访问,支持数万 QPS 并发编号生成
-
宕机时已有缓存号段不丢失
-
可灵活配置号段粒度(每次取 1000、10000)
public class SegmentIdService {
private AtomicLong current;
private long max;
public synchronized String getNextId() {
if (current.get() < max) {
return format(current.getAndIncrement());
} else {
loadNextSegment(); // DB取下一个段
return getNextId();
}
}
}
🧪 实战优化经验总结
✅ 经验 1:按业务划分编号维度
-
不同业务类型(订单、发票、退货)使用不同编号策略,避免资源冲突
✅ 经验 2:按租户分段号段
-
多租户系统中,建议将号段分租户隔离存储,支持租户编号前缀
✅ 经验 3:设置号段提前预警机制
-
如果当前缓存使用超过 80%,异步预加载下一段,避免阻塞等待
✅ 经验 4:编号不需要数据库“回写”
-
实践中避免每次生成编号都回写数据库,增加延迟
+-----------------------------+
| 配置管理中心 |
| - 规则管理(前缀、格式) |
| - 租户号段定义 |
+-----------------------------+
|
v
+-----------------------------+
| 号段分发服务 |
| - 本地缓存段 |
| - 异步加载下一段 |
+-----------------------------+
|
v
+-----------------------------+
| 数据库持久层 |
| - 当前号段最大值 |
| - 并发锁/乐观锁控制 |
+-----------------------------+
✅ 结语:统一编号中心是系统演进的必经之路
编号从来不是“业务小事”,而是系统稳定性、架构成熟度的晴雨表。
尤其是 SaaS、分布式、多租户架构中,单号的生成逻辑背后隐藏着:
-
服务拆分的边界认知
-
多业务协同的策略统筹
-
高并发环境下的数据一致性治理
建议任何一个中大型系统,在并发瓶颈出现之前,主动设计编号中心,避免“小问题拖垮大系统”。