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


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