高并发下唯一订单号生成器【16位数字订单号】

参考:常用的分布式ID方案

快速查询设计

带业务含义的编号,可以用来进行快速查询设计

高并发下唯一订单号生成思考?

订单号3个性质:1.唯一性  2.不可推测性 3.效率性

可选方案一 
本方案使用的是当前时间,包括毫秒数、纳秒数,不需要数据库参与计算,性能不用说。

public static String genId(String machineId){
    String orderId =
            machineId +
                    (System.currentTimeMillis() + "").substring(1) +
                    (System.nanoTime() + "").substring(7, 10);
    System.out.println(orderId);
    return orderId;
}

讲解:
参数machineId:是集群时的机器代码,可以1-9任意。部署时,分别为部署的项目手动修改该值,以确保集群的多台机器在系统时间上不一致的问题(毫无疑问每台机器的毫秒数基本上不一致)。
参数System.currentTimeMillis():这是java里面的获取1970年到目前的毫秒数,是一个13位数的数字,与Date.getTime()函数的结果一样,比如1378049585093。经过研究,在2013年,前三位是137,在2023年是168,到2033年才199.所以,我决定第一位数字1可以去掉,不要占位置了。可以肯定绝大多数系统用不了10年20年。这样,参数2就变成了12位数的数字,加上参数1machineId才13位数。
参数System.nanoTime():这是java里面的取纳秒数,经过深入研究,在同一毫秒内,位置7,8,9这三个数字是会变化的。所以决定截取这三个数字出来拼接成一个16位数的订单号。
总结:理论上此方案在同一秒内,可以应对1000*1000个订单号,但是经过测试,在每秒并发2000的时候,还是会出现2-10个重复。

可选方案二
本方案基于UUID。
UUID是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的,这个不重复性全世界人民都知道。当然,既然字符串值不重复,那对应的hashCode也是一样,不会重复。
算法:

Java代码  
  1. OrderId=  
  2. machineId+  
  3. UUID.randomUUID().toString().hashCode();  


讲解:
参数1不再解释。
参数2是值生成UUID然后取它的hashCode值,经过测试,完全没有一点问题。您可以开1000w的并发去测试插入吧,只要数据库不会报唯一性错误,那就没问题。
总结:
hashCode这个算法从搞软件开始到现在这么多年,一直没派上用场,这次大大的用上了。解决了问题。请同志们以后善用这个东西。
5、 附录:方案二的算法代码

public static String getOrderIdByUUId(String machineId) {

    int hashCodeV = UUID.randomUUID().toString().hashCode();
    if (hashCodeV < 0) {//有可能是负数
        hashCodeV = -hashCodeV;
    }
    // 0 代表前面补充0
    // 4 代表长度为4
    // d 代表参数为正数型
    String orderId=machineId + String.format("%015d", hashCodeV);
    System.out.println(orderId);
    return orderId;
}


方案二其实也就一个函数,很简便。缺点:无序性。

方案三、Snowflake

64位ID (42(毫秒)+5(机器ID)+5(业务编码)+12(重复累加))

  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江晓曼*凡云基地

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值