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

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

  

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()方法,该方法是订单号生成的一个亮点,也是支持可以高并发的主要缘由。app

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

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

  若是 key 不存在,那么 key 的值会先被初始化为 0 ,而后再执行 INCR / DECR 操做。spa

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

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

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

相关文章
相关标签/搜索