<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          聊聊接口冪等性設(shè)計(jì)

          共 2753字,需瀏覽 6分鐘

           ·

          2021-07-02 09:59

          相關(guān)閱讀

          300本計(jì)算機(jī)編程的經(jīng)典書籍下載

          AI全套:Python3+TensorFlow打造人臉識(shí)別智能小程序

          最新人工智能資料-Google工程師親授 Tensorflow-入門到進(jìn)階

          Java架構(gòu)全階段七期完整

          黑馬頭條項(xiàng)目 - Java Springboot2.0(視頻、資料、代碼和講義)14天完整版

          Spring核心編程思想

          作者:pikaxiao

          來源:blog.csdn.net/qq_36011946/article/details/104200262


          冪等性設(shè)計(jì)

          今天我們來聊聊接口的冪等性設(shè)計(jì),所謂冪等,就是任意多次執(zhí)行所產(chǎn)生的影響均與一次執(zhí)行的影響相同。 冪等性接口是指可以使用相同參數(shù)重復(fù)執(zhí)行,并能獲得相同結(jié)果的接口。這里就不展開數(shù)學(xué)中的定義了,有興趣的可以自行g(shù)oogle。

          為什么接口需要冪等呢?

          我們都知道,作為接口的調(diào)用方,對(duì)于接口調(diào)用的結(jié)果,一般會(huì)返回成功、失敗和超時(shí)。對(duì)于成功和失敗,都是明確的狀態(tài),調(diào)用放可以根據(jù)結(jié)果做相應(yīng)的處理,但是對(duì)于超時(shí),由于不確定是否成功請(qǐng)求了,作為調(diào)用方來說,所以一般都會(huì)選擇重試。而重試就會(huì)出現(xiàn)定義中描述的多次執(zhí)行。

          可以從下面這個(gè)例子中加深一下理解:

          • 創(chuàng)建訂單時(shí),需要減庫(kù)存,如果減庫(kù)存接口超時(shí)了,調(diào)用方重新調(diào)用一次(無論是否成功的執(zhí)行了減庫(kù)存代碼),應(yīng)該要保證不會(huì)多減一次庫(kù)存。

          要保證不會(huì)多件一次庫(kù)存,一般有兩種做法:

          • 接口提供方需要提供相應(yīng)的查詢接口。調(diào)用方在超時(shí)后去查詢一下是否成功。是否多扣一次庫(kù)存掌握在調(diào)用方手里。如果接口是提供給第三方使用的,就會(huì)存在一定的風(fēng)險(xiǎn)。
          • 接口支持冪等。這樣冪等的保證完全掌握在提供方自己手里,完全不用擔(dān)心。

          全局ID

          要讓接口支持冪等,要怎么做呢,你可能會(huì)想到在減庫(kù)存之前增加一次查詢,已經(jīng)減過的直接返回不就完事了么?這樣確實(shí)能達(dá)到目的,可是會(huì)額外多了一次查詢,有沒有什么更優(yōu)的方法呢?

          要保證減庫(kù)存操作的唯一性,可以在接口上多加一個(gè)參數(shù),這個(gè)參數(shù)必須全局唯一,數(shù)據(jù)庫(kù)設(shè)計(jì)表的時(shí)候這個(gè)字段要加上唯一索引,當(dāng)多次保存相同數(shù)據(jù)的時(shí)候,數(shù)據(jù)庫(kù)就會(huì)報(bào)錯(cuò),這就證明了接口已經(jīng)成功調(diào)用過,可以直接返回。

          那這個(gè)全局ID由誰來分配呢?

          1.可以創(chuàng)建一個(gè)分配中心,由中心統(tǒng)一分配。

          優(yōu)點(diǎn):分配ID與業(yè)務(wù)集群解耦。

          缺點(diǎn):需要單獨(dú)維護(hù)分配中心,這個(gè)分配中心也必須做成高可用集群,增加維護(hù)成本。

          2.集成在業(yè)務(wù)服務(wù)集群。

          優(yōu)點(diǎn):業(yè)務(wù)服務(wù)集群本來就是高可用的,無需提供額外保證。

          缺點(diǎn):分配ID與業(yè)務(wù)耦合(這其實(shí)沒什么影響),需要保證業(yè)務(wù)服務(wù)集群生成ID的唯一性。

          一般來說,后者是比較好的方案,我們只要提供一個(gè)能在集群上生成全局唯一ID的算法即可。

          除了保證全局唯一,最好具備以下特點(diǎn)(非必須):

          • 遞增,起碼保證每臺(tái)機(jī)器上的ID遞增。(保證數(shù)據(jù)庫(kù)性能)
          • 明確的規(guī)則,ID的各個(gè)位都有具體的定義。(方便追溯)

          接下來就來說說現(xiàn)階段常用的全局ID算法。

          UUID

          UUID設(shè)計(jì)的目的就是讓分布式系統(tǒng)中的所有元素,都能有唯一的辨識(shí)信息,而不需要通過中央控制端來做辨識(shí)信息的指定。關(guān)于UUID的設(shè)計(jì)原理可自行Google。

          優(yōu)點(diǎn):實(shí)現(xiàn)簡(jiǎn)單(大多數(shù)編程語言都集成到工具庫(kù)了),本地生成,性能好,擴(kuò)展性高,不需要協(xié)定。

          缺點(diǎn):無法遞增(消耗數(shù)據(jù)庫(kù)性能)、UUID過長(zhǎng)(消耗存儲(chǔ)空間)。

          在中小型項(xiàng)目中,UUID會(huì)是不錯(cuò)的選擇。為什么這么說呢?面對(duì)并發(fā)度不高的系統(tǒng),數(shù)據(jù)庫(kù)性能一般不會(huì)達(dá)到瓶頸,所以說UUID是犧牲數(shù)據(jù)庫(kù)性能換取其優(yōu)點(diǎn)的一種選擇。

          Snowflake

          Snowflake是Twitter 的開源項(xiàng)目,它生成的ID是64bit的正整數(shù),結(jié)構(gòu)如圖:

          • 1bit:固定為0,二進(jìn)制中最高位為符號(hào)位,0為整數(shù),1位負(fù)數(shù)。所以固定為0表示生成的ID都為正數(shù)
          • 41bit:作為毫秒數(shù),大約能用69年。
          • 10bit:作為機(jī)器編號(hào)(5bit是數(shù)據(jù)中心ID,5bit為機(jī)器ID)。支持1204個(gè)實(shí)例。
          • 12bit:序列號(hào),一毫秒最多生成2^12=4096個(gè)。
          • 在公眾號(hào)后端架構(gòu)師后臺(tái)回復(fù)“架構(gòu)整潔”,獲取一份驚喜禮包。

          優(yōu)點(diǎn):遞增,且按時(shí)間有序。性能高,可根據(jù)情況分配bit。

          缺點(diǎn):依賴機(jī)器時(shí)鐘。在分布式系統(tǒng)中,各個(gè)機(jī)器上的時(shí)間不可能完全一樣,在同步各機(jī)器的時(shí)間時(shí),可能會(huì)造成重復(fù)ID。

          在高并發(fā)的業(yè)務(wù)下,Snowflake生成的整數(shù)ID的存儲(chǔ)和讀取性能都要優(yōu)于UUID。現(xiàn)階段國(guó)內(nèi)有很多基于Snowflake算法的特定實(shí)現(xiàn),比如百度的UidGenerator。

          關(guān)于Redis和MongoDB的設(shè)計(jì)這里就不展開了。畢竟要強(qiáng)依賴于存儲(chǔ)系統(tǒng),添加了維護(hù)成本和風(fēng)險(xiǎn)點(diǎn)。

          業(yè)務(wù)邏輯

          正如我們前面講過的,要依賴于數(shù)據(jù)庫(kù)唯一性約束,當(dāng)數(shù)據(jù)庫(kù)報(bào)唯一性沖突時(shí),就說明這個(gè)求情已經(jīng)成功過了,不用再執(zhí)行,直接返回即可。

          HTTP的冪等性

          這里給出http請(qǐng)求的冪等性要求:

          對(duì)于POST方法,可能會(huì)出現(xiàn)多次提交的問題,比如由于網(wǎng)絡(luò)不好等原因,造成請(qǐng)求超時(shí),這是用戶再點(diǎn)一次提交按鈕。對(duì)此一般的冪等性解決方法如下:

          在提交的表單隱藏一個(gè)全局ID,這個(gè)全局ID需要提前向后端獲取,提交的時(shí)候把這個(gè)ID一起提交過來,按照上圖所描述的業(yè)務(wù)邏輯,來支持冪等。后端成功以后前端跳轉(zhuǎn),跳轉(zhuǎn)到GET請(qǐng)求,把剛才提交的數(shù)據(jù)展示出來。

          小結(jié)

          這篇講了冪等性設(shè)計(jì)的要點(diǎn),并給出了設(shè)計(jì)方案,大家可根據(jù)具體情況選擇合適的方案。



          看完本文有收獲?請(qǐng)轉(zhuǎn)發(fā)分享給更多人


          往期資源:


          Flutter 移動(dòng)應(yīng)用開發(fā)實(shí)戰(zhàn) 視頻(開發(fā)你自己的抖音APP)
          Java面試進(jìn)階訓(xùn)練營(yíng) 第2季(分布式篇)
          Java高級(jí) - 分布式系統(tǒng)開發(fā)技術(shù)視頻


          瀏覽 72
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  午夜影院无码免费 | 在线观看免费黄色小视频 | 国产成人综合久久久久久 | 久久精品国产99国产精品导航 | 午夜理论免费毛片 |