分布式环境下设备连续唯一序列号预留方案咨询
解决多工位烧录序列号预留异常导致断档的方案
问题本质
多烧录工位按设备类型申请连续序列号,当前用in progress标记预留状态,但如果工位软件崩溃、网络断连这类异常发生,这些预留的序列号就会一直卡着,最后导致对应设备类型的序列号出现间隙,没法保证连续性。现有表字段:device type、serial、status、prod date。
可行解决思路
1. 给预留序列号加超时自动回收
- 给表新增
expire_time字段,每次生成预留条目时,设置一个合理的超时时间(比如15分钟,根据实际烧录流程时长调整)。 - 部署定时任务:用数据库定时任务或者单独的小服务,定期扫描所有
status='in progress'且expire_time < 当前时间的条目,将它们的status改为expired,或者直接删除这些条目。 - 补充逻辑:工位下次请求序列号时,优先分配这些过期回收的序列号,用完后再分配新的连续号,确保序列连续性。
2. 预分配序列号段代替单条分配
- 不再单次分配单个序列号,改为按设备类型预分配一段连续号(比如一次分配10个)给工位:
- 数据库维护每个设备类型的
current_max_serial字段,工位请求时,通过分布式锁保证原子性,将current_max_serial增加预分配数量,返回序列号段范围(比如原max为100,加10则返回101-110)。 - 工位在本地管理这段序列号,烧录成功就标记对应序列号为
done,失败则直接跳过该序列号(后续可记录失败原因,但不影响全局连续性,跳过的号可后续补烧或标记废弃)。 - 配套定时任务:记录每个工位分配的序列号段及过期时间,超时后将未使用的号归还给全局序列,避免浪费。
- 数据库维护每个设备类型的
3. 两阶段确认+补偿机制
- 分两步执行序列号分配:
- 工位请求序列号,数据库生成
status='reserved'的条目,返回序列号给工位。 - 烧录成功后调用确认接口将
status改为done;烧录失败则调用取消接口将status改为cancelled。
- 工位请求序列号,数据库生成
- 补偿定时任务:扫描
status='reserved'且创建时间(可复用prod date或新增create_time)超过阈值的条目,要么调用工位状态查询接口确认该序列号是否烧录成功,无法查询则直接标记为cancelled,允许重新分配。
4. 拆分序列号池与使用记录
- 设计两张表拆分逻辑:
serial_pool:存储所有待分配的连续序列号,按设备类型分组,状态为available或allocated。serial_usage:存储已成功烧录的序列号,状态为done。
- 工位请求时,从
serial_pool取出最小的available序列号,标记为allocated后返回。 - 烧录成功则将该序列号从
serial_pool迁移至serial_usage(或直接更新serial_pool状态为done);烧录失败则将serial_pool中该序列号改回available,供下次分配。 - 定时任务定期将长时间处于
allocated状态的序列号改回available。
关键注意点
- 所有序列号状态变更操作必须保证原子性,避免并发冲突,比如使用数据库事务、行级锁。
- 超时时间需结合实际烧录流程时长设置,过短可能误回收正常流程的序列号,过长则会让间隙持续更久。
- 预分配序列号段的大小要适配工位负载,过大易浪费序列号,过小则会增加数据库交互频率影响性能。
内容的提问来源于stack exchange,提问作者MPH
相关产品推荐
相关产品推荐

