1. 程式人生 > >高併發下唯一訂單號生成器【16位數字訂單號】

高併發下唯一訂單號生成器【16位數字訂單號】

高併發下唯一訂單號生成思考?

訂單號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;
}


方案二其實也就一個函式,很簡便。

相關推薦

併發唯一訂單生成器16數字訂單

高併發下唯一訂單號生成思考? 訂單號3個性質:1.唯一性 2.不可推測性 3.效率性可選方案一 本方案使用的是當前時間,包括毫秒數、納秒數,不需要資料庫參與計算,效能不用說。 public static String genId(String machineId){

大規模叢集的Hadoop併發以及高效能架構原理總結石杉的架構筆記

歡迎關注個人公眾號:石杉的架構筆記(ID:shishan100) 週一至週五早8點半!精品技術文章準時送上! “ 又到週末,老規矩,週末不給大家送上“燒腦”的技術文章,我們稍微停一下腳步,總結一下之前的內容,溫故而知新。 前言 這次我們總結的,主要是之前大資料的內容。這裡筆者多說一句,筆者認為

java web系統在併發如何實現訂單生成唯一

java web系統在高併發下如何實現訂單號生成唯一? 系統訂單號規則:XXXX(固定字元)+年(後兩位)月日+流水號。流水號每天重新從1開始。 系統訂單號產生唯一的方案有哪幾種?由於訂單號規則已經確定,無法使用時間戳及隨機數,有哪些方案可以使用? 注:資料庫mysql,訂單號不是訂單表的主鍵

併發怎樣生成唯一訂單

方案一: 如果沒有併發,訂單號只在一個執行緒內產生,那麼由於程式是順序執行的,不同訂單的生成時間戳正常不同,因此用時間戳+隨機數(或自增數)就可以區分各個訂單。 如果存在併發,且訂單號是由一個程序中的多個執行緒產生的,那麼只要把執行緒ID新增到序列號中就可以保證訂單號唯一。

併發生成自定義規則的訂單

目錄 背景 規則 問題 分析 思路 資料庫 執行緒鎖 方案 討論 背景 半年以前做的一個流程相關的專案,近期在做效能測試;之前的功能測試已經做完了,都沒有什麼問題。    專案採用的springmvc框架,生成訂單號以及儲存訂單號都是在activ

併發訂單與庫存的處理

問題:一件商品只有100個庫存,現在有1000或者更多的使用者來購買,每個使用者計劃同時購買1個到幾個不等商品。如何保證庫存在高併發的場景下是安全的。 1.不多發 2.不少發 下單涉及的一些步驟 1.下單 2.下單同時預佔庫存 3.支付 4.支付成功真正減扣庫存 5.取消訂

MySQL 在併發訂單撮合 系統使用 共享鎖 與 排他鎖 保證資料一致性

作者:林冠巨集 / 指尖下的幽靈 掘金:juejin.im/user/587f0d… 部落格:www.cnblogs.com/linguanh/ GitHub : github.com/af913337456… 騰訊雲專欄: cloud.tencent.c

併發使用Redis生成唯一id

最近使用spirngcloud來搭建分散式專案,遇到插入重複問題,決定用redis生成唯一ID來解決。 /** * 獲取唯一Id * @param key *

併發的基礎優化(三)——訂單主鍵(終)

具體不說了,看上一篇。開發框架spring4.2.9-springmvc-hibernate4.3.11Final,需要包的可以在我的資源裡找。由於這些類都要封裝進dao基類中,所以就不交給spring管理了,註解都去掉。方便大家參考依賴,保留import,看別人的程式碼不貼

搶購/秒殺redis實現併發的搶購/秒殺功能

開發十年,就只剩下這套架構體系了! >>>   

MySQL在併發訂單撮合、系統使用、共享鎖與排他鎖保證資料一致性

前序 距離上次擇文發表,兩月餘久。2018年也即將要結束了,目前的工作依然是與區塊鏈應用相關的,也很榮幸在9月初受邀簽約出版暫

HttpClient併發效能優化-http連線池

首先,明確兩點: 1.http連線池不是萬能的,過多的長連線會佔用伺服器資源,導致其他服務受阻 2.http連線池只適用於請求是經常訪問同一主機(或同一個介面)的情況下 3.併發數不高的情況下資源利用率低下 那麼,當你的業務符合上面3點,那麼你可以考慮使用http連線池來提高伺服器效能

spring cache redis 併發返回null

在使用springdata操作快取中,當訪問量比較大時,有可能返回null導致資料不準確,發生機率在0.01%或以下,雖然已經低於壓測標準,但是還是會影響部分使用者,經過一番篩查,發現原因如下: RedisCache 類中 有get方法,存在明顯的邏輯錯誤 “先判斷是否存在,再去get”,程

分析一個在併發的財務支付鎖的問題

在工作專案中,會遇到一些php併發訪問去修改一個數據問題,如果這個資料不加鎖,就會造成資料的錯誤。下面將分析一個財務支付鎖的問題。希望對大家有所幫助。   1,在沒有應用鎖機制的情況下 1.1 財務支付簡化版本程式碼 <!--?php  /** 

併發防止商品超賣的Redis實現

@RestController @RequestMapping("/rushbuy") @Slf4j public class RushbuyController { @Autowired private RedisTemplate redisTemplate; //釋出

併發的庫存減少問題(微信支付)

前段時間,在做一個網上商場的專案。在做秒殺模組時候,遇到一個棘手的問題。就是我設定的秒殺活動的庫存,總是莫名其妙的減少了。我是把減庫存放在微信支付的成功回撥裡面的。 查詢資料發現,原來微信支付成功之後微信伺服器會發送8次請求到回撥地址。這樣我這樣的做法就會導致庫存減少。 微信支付回撥會返回微

併發Redis如何保持資料一致性(避免讀後寫)

本文轉自部落格:https://blog.csdn.net/u011832039/article/details/78924418 ----------------------------------------------------------------------------------

併發System.currentTimeMillis()併發問題以及優化對比

前言 在高併發場景下System.currentTimeMillis()併發問題嚴重,甚至比建立一個普通物件要耗時的多;在系統中有時候不可避免要列印一些時間戳,但怎麼做才更好呢。 程式碼實現 iimport java.util.concurrent.Execut

併發的Java資料結構(List,Set,Map,Queue)

由於並行程式與序列程式的不同特點,適用於序列程式的一些資料結構可能無法直接在併發環境下正常工作,這是因為這些資料結構不是執行緒安全的。本節將著重介紹一些可以用於多執行緒環境的資料結構,如併發List、併發Set、併發Map等。 1.併發List Vector 或者 CopyOnWriteArrayList 是

併發map和chan實現的連結池的執行緒安全及效率

1.背景 上一次blog寫著寫著崩掉了,這次一定寫完一節儲存一節。 目前從事go語言的後臺開發,在叢集通訊時需要用到thrift的rpc。由於叢集間通訊非常頻繁且併發需求很高,所以只能採用連線池的形式。由於叢集規模是有限的,每個節點都需要儲存平行節點的連線,所以