1.介紹
今天做了一個功能,生成訂單流水號,當然這其實這並不是一個很難的功能,最直接的方式就是日期+主機Id+隨機字符串來拼接一個流水號。但是今天有個我認為比較優雅方式來實現。我要介紹是日期+ long(商家Id+訂單類型+主機ID+AtomicInteger),什么意思呢,前面的日期保持不變,后面的將商家Id,訂單的類型,主機的Id,AtomicInteger,通過移位與或運算“保存”到一個long類型里面。為什么要這么做?
- 不想把相關信息直接暴露出去。
- 通過流水號可以快速得到相關業務信息,快速定位問題。
- 使用AtomicInteger可提高並發量,降低了沖突。
2.原理解釋
前面的生成日期就不需要講了,直接講解如何通過移位和與或操作得到long值。
先來看張圖:
這是一個我設計的long存儲形式,大家可以格局自身業務來自行設計,什么業務數據占的位數。現在來詳細解釋下。
- 符號位,這個不用過的介紹,大家都知道2進制第一位都是符號位,0表示正數1表示負數
- 當前秒數,表述的是當前是當天的第多少秒,每天最多有86400秒,最多占17位
- 商家Id占14位,由於業務涉及到商戶,訂單也是歸為每個商戶下面的,假定我們的最多有9999家商戶,9999占位是14位,所以我們商戶Id占14位,大家根據自身業務的量來決定長度。
- 訂單類型,假定我們的訂單類型還停留在10種以內,所以我們保留4位,最多支持類型16種,大家同樣的根據業務的量來決定
- 服務器的Id,假定服務器數量在10台以內,所以我們保留4位,最多支持16台服務器,大家同樣的根據自身服務器的數量來決定。,
- 剩下的24位全部留給AtomicInteger,設計上我這里的qps可以達到2的24方。這個其實已經很大了。大家根據上面的設計留下來的數量當AtomicInteger位數,其實可以滿足大部分業務需求了。
介紹了具體的原理,現在要上代碼了。
3.show code
運行測試結果: