【开发笔记】-高并发订单号生成策略


  之前一直在思考高并发环境下怎样生成唯一订单号,考虑过时间戳、UUID等,但都不是十分满意,直到最近看到公司的订单号的生成方式,感觉还是比较完美的一种解决方式。在这里记录一下公司的订单号的生成方式。

  

public static long getOrderId() {
   //设置订单号前缀(可以根据数据环境/地区的不同来设置不同订单号前缀) String ordernoIndex
= PropertiesManager.getPropertiesValue("key");//从配置中心获取订单号前缀 if(StringUtils.isBlank(ordernoIndex)){ ordernoIndex = ""; }
   //从redis中获取订单号
long orderId = JedisManager.incr(REDIS_ORDER_KEY, CART_REDIS_POOL);
   //判断订单号是否小于订单号初始值
if(orderId < orderIdInitValue){
     //设置redis中orderNo的初始值 JedisManager.setString(REDIS_ORDER_KEY, String.valueOf(orderIdInitValue),
0, CART_REDIS_POOL); orderId = JedisManager.incr(REDIS_ORDER_KEY, CART_REDIS_POOL); }
   //拼接订单号(订单前缀+redis中的自增长值),并返回
return Long.valueOf(new StringBuffer().append(ordernoIndex).append(String.valueOf(orderId)).toString()); }

  订单前缀可以设置在订单中心或配置文件里,这样可以在不同环境获得不同的订单号,避免因不同数据中心,导致出现订单号重复的情况。 

  JedisManager.incr()方法,该方法是订单号生成的一个亮点,也是支持能够高并发的主要原因。

  Incr 命令会将 redis的key 中储存的数字值增一

  decr 命令会将 redis的key 中存储的数字值减一。

  如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR / DECR 操作。

  如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。

  之前看到过说 Incr 命令最高支持每秒1000万级别的递增(没有测试过),且该命令支持原子性,用来生成订单号来说还是比较轻松的。

  同样的该方式也适用于 ”秒杀“库存的递减 等场景。  

 

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM