分布式服務(wù)的冪等性設(shè)計,值得學(xué)習(xí)!

Java技術(shù)棧
www.javastack.cn
關(guān)注閱讀更多優(yōu)質(zhì)文章
為什么需要保證冪等性
是否會導(dǎo)致最終創(chuàng)建了兩條一樣的訂單? 是否會扣除兩遍庫存? 是否會重復(fù)扣除用戶的錢?
唯一ID
就上面的冪等性下單接口來說,要做到冪等性,就需要借助一個唯一的ID來標(biāo)志每次交易。唯一ID的分配可以有幾種方式:
由一個統(tǒng)一的ID分配中心來分配。
由上游服務(wù)來生成唯一ID,但必須保證不產(chǎn)生沖突的ID。
采用統(tǒng)一的分配中心來分配唯一ID時,業(yè)務(wù)方每次調(diào)用接口都多了一次調(diào)用分配中心獲取唯一ID的請求。這多了額外的開銷。
獲取唯一ID有一種方式,是借助mysql的自增索引,這其實(shí)也是一個ID分配中心。對服務(wù)性能有苛刻要求時,可以采用第二種方式,由主調(diào)服務(wù)本身來生成這個唯一ID。關(guān)注公眾號Java技術(shù)??梢垣@取MySQL系列教程。
為了保持不會產(chǎn)生重復(fù)的ID,可以使用一下幾種ID生成方法:
UUID
UUID的全稱是Universally Unique Identifier,通用唯一識別碼。
具體可以看維基百科的介紹:https://en.wikipedia.org/wiki/Universally_unique_identifier
UUID是一個128bit的數(shù)字,用于標(biāo)志計算機(jī)的信息,雖然UUID不能保證絕對不重復(fù),但重復(fù)的概率小到可以被忽略。UUID的生成沒有什么規(guī)律,為了保證UUID的唯一性,規(guī)范定義了包括網(wǎng)卡MAC地址、時間戳、名字空間(Namespace)、隨機(jī)或偽隨機(jī)數(shù)、時序等元素,以及從這些元素生成UUID的算法。這也就意味著:
128bit,占據(jù)了太多的內(nèi)存空間
生成的ID不是人可以看懂的
無法保證ID的遞增,某些場景需要按前后排序 無法滿足。
這是一個在線生成UUID的網(wǎng)站:https://www.uuidgenerator.net/ 你可以直觀感受一下UUID。
Snowflake
這是Twitter的一個開源項目,它是一個分布式ID的生成算法,它會產(chǎn)生一個long類型的唯一ID,其核心算法是:
時間部分:41bit作為毫秒數(shù),大概可以使用69.7年
機(jī)器編號部分:10bit作為機(jī)器編號,支持1024個機(jī)器實(shí)例。
毫秒內(nèi)的序列號:12bit,一毫米可以生成4096個序列號

網(wǎng)上有各種語言實(shí)現(xiàn)的Snowflake算法的實(shí)現(xiàn),有興趣的閱讀一下實(shí)現(xiàn)代碼。
實(shí)際上,redis 或是 mongoDB 的全局ID生成器的算法和Snowflake算法大同小異。這是基于redis的分布式ID生成器實(shí)現(xiàn):https://github.com/hengyunabc/redis-id-generator
它的核心思想是:
使用41 bit來存放時間,精確到毫秒,可以使用41年。
使用12 bit來存放邏輯分片ID,最大分片ID是4095
使用10 bit來存放自增長ID,意味著每個節(jié)點(diǎn),每毫秒最多可以生成1024個ID
共享存儲
避免不必要的查詢
insert?into?... values?... on?DUPLICATE?KEY?UPDATE?...作者:melonstreet
來源:https://www.cnblogs.com/QG-whz/
版權(quán)申明:本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利。






關(guān)注Java技術(shù)??锤喔韶?/strong>


