需求
有个生成订单号的需求,对于生成订单号有如下要求
- 不能被猜出订单量
- 唯一性
- 趋势递增
- 订单号包含时间信息
- 防止race condition生成重复的id
- 防止时间回拨生成重复的id
- 满足每秒可以生成1w个订单号
- 订单号不能过长
分析
- 不能被猜出订单量,所以自增id排除掉
- 要求趋势递增,所以uuid排除掉
- 订单号不能过长,所以snowflake、Mongdb objectID之类的排除掉
方案
订单号=12位时间信息+4位随机数
。时间信息精确到秒,加上4位随机数,支持每秒最多生成1w个订单号。
利用redis来实现方案。
incr命令
防止4位随机数重复。初始化的时候就设置一个随机数,而不是从0开始incr。类型TCP协议的ISN(Initial Sequence Number)
time命令
获取redis服务器的时间,防止各机器本地时间不一致,导致订单号重复。
lua脚本
确保原子性,避免race condition.
set命令
指定nx参数,避免race condition.
由于redis用的是AWS的服务,所以高可用性可以保障。
伪代码如下
def