【開發筆記】-高併發訂單號生成策略

  以前一直在思考高併發環境下怎樣生成惟一訂單號,考慮過期間戳、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

  一樣的該方式也適用於 」秒殺「庫存的遞減 等場景。  字符串

相關文章
相關標籤/搜索