<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>

          面試必問(wèn):接口冪等性

          共 2611字,需瀏覽 6分鐘

           ·

          2024-04-17 18:17

          歡迎關(guān)注微信公眾號(hào):互聯(lián)網(wǎng)全棧架構(gòu)

          總體介紹


          冪等(Idempotence)是一個(gè)計(jì)算機(jī)領(lǐng)域中的概念,通俗來(lái)講,如果用戶對(duì)一個(gè)操作發(fā)起一次或者多次請(qǐng)求,得到的結(jié)果都是一樣的,那么就認(rèn)為這樣的操作是冪等的。HTTP規(guī)范對(duì)于冪等的說(shuō)明如下:

          A request method is considered idempotent if the intended effect on the server of multiple identical requests with that method is the same as the effect for a single such request.

          冪等性主要是指重復(fù)請(qǐng)求的場(chǎng)景,比如:

          • 用戶多次點(diǎn)擊提交按鈕
          • 由于網(wǎng)絡(luò)原因觸發(fā)了重試機(jī)制

          • 頁(yè)面回退后再次提交

          • 消息重復(fù)消費(fèi)


          簡(jiǎn)單來(lái)講,接口最終都是對(duì)于數(shù)據(jù)的操作,也就是數(shù)據(jù)庫(kù)的增刪改查(CRUD),我們來(lái)分析一下,在發(fā)起多次相同的請(qǐng)求時(shí),這些操作的冪等性:

          冪等性的解決方案


          一、添加唯一索引

          根據(jù)業(yè)務(wù)場(chǎng)景,在數(shù)據(jù)庫(kù)表中添加唯一索引,這樣的話,如果向數(shù)據(jù)庫(kù)中插入已經(jīng)存在的業(yè)務(wù)數(shù)據(jù),系統(tǒng)就會(huì)拋出異常,避免了重復(fù)數(shù)據(jù)的插入。

          比如一個(gè)訂單系統(tǒng),把訂單號(hào)作為唯一索引,前端提交訂單之前,請(qǐng)求發(fā)號(hào)器生成一個(gè)訂單號(hào),然后把訂單號(hào)加入到請(qǐng)求頭中,后端程序保存訂單信息到數(shù)據(jù)庫(kù)中,如果拋出異常,數(shù)據(jù)不會(huì)重復(fù)插入,但可以向用戶返回下單成功的提示:

          當(dāng)然,這種方式完全依賴數(shù)據(jù)庫(kù)的唯一索引特性,雖然很安全,很好地避免了數(shù)據(jù)重復(fù)問(wèn)題,但把問(wèn)題全部拋給了數(shù)據(jù)庫(kù)層面,會(huì)導(dǎo)致性能問(wèn)題,同時(shí),即使是數(shù)據(jù)重復(fù)了,也提示下單成功,對(duì)于用戶不太友好。

          二、數(shù)據(jù)庫(kù)樂(lè)觀鎖
          在并發(fā)業(yè)務(wù)系統(tǒng)中,樂(lè)觀鎖也是經(jīng)常采用的一種手段,而這種樂(lè)觀鎖的機(jī)制主要用于更新操作。基本的做法是在數(shù)據(jù)庫(kù)表中添加一個(gè)version字段,每次更新操作都把此字段的值加一,并且在更新的時(shí)候做一下版本判斷。

          下面我們以一個(gè)實(shí)例來(lái)演示一下這種做法,假如訂單表中的數(shù)據(jù)如下:

          這時(shí)候,如果我們想更新訂單號(hào)1003的金額為102,那么我們需要首先把這個(gè)訂單號(hào)的version查出來(lái),結(jié)果是5,然后再更新amount字段,像下面這個(gè)sql:

          UPDATE orders SET amount=102,version=version+1 WHERE order_id=1003 AND version=5

          在上面的更新語(yǔ)句中,WHERE條件把version=5也加上了,如果這個(gè)更新操作有重復(fù)請(qǐng)求,那么最終也只有一條sql能夠真正更新數(shù)據(jù),因?yàn)槠渲幸粭lsql更新成功后,version就等于6了,其他的sql就沒(méi)有滿足條件的數(shù)據(jù)了。

          三、使用redis+token

          使用redis+token的機(jī)制來(lái)保證冪等性是非常常見的一種手段,需要前后端配合一起來(lái)實(shí)現(xiàn),前端首先向后端請(qǐng)求一個(gè)token,后續(xù)的請(qǐng)求中再帶上這個(gè)token,接下來(lái)服務(wù)器再判斷redis中是否存在這個(gè)token,如果存在,則進(jìn)行后續(xù)的業(yè)務(wù)操作,否則說(shuō)明此請(qǐng)求為重復(fù)請(qǐng)求。

          在高并發(fā)的場(chǎng)景下,有一個(gè)問(wèn)題需要考慮,是在業(yè)務(wù)操作前刪除token,還是在業(yè)務(wù)操作結(jié)束之后再刪除token?

          如果是在業(yè)務(wù)操作前刪除token,如果業(yè)務(wù)操作執(zhí)行失敗了,但還沒(méi)有向客戶端返回處理結(jié)果,此時(shí)客戶端又進(jìn)行了重試,但此時(shí)token已經(jīng)刪除,那么重試的請(qǐng)求就不再進(jìn)行業(yè)務(wù)操作了(比如生成訂單這樣的操作)。

          如果先進(jìn)行業(yè)務(wù)操作,再刪除token呢?也會(huì)有問(wèn)題,比如第一次的業(yè)務(wù)操作還沒(méi)有結(jié)束,第二次請(qǐng)求又過(guò)來(lái)了,這時(shí)token還存在,所以第二次請(qǐng)求也會(huì)繼續(xù)執(zhí)行,顯然這是不合理的。

          一般情況下,可以采用先刪除token的方式,因?yàn)檫@種方式的結(jié)果是沒(méi)有進(jìn)行業(yè)務(wù)操作,后續(xù)再重新獲取token進(jìn)行操作即可,相對(duì)而言要更合理一些。

          三三

          總結(jié)


          接口冪等性是并發(fā)編程中非常重要的概念,也是各個(gè)公司面試中常問(wèn)的一個(gè)問(wèn)題,本文總結(jié)了常見的實(shí)現(xiàn)冪等性的幾種方案,相對(duì)來(lái)講,使用redis+token的方式是一種比較常見且有效的方式,可以滿足很多場(chǎng)景的需求。

          當(dāng)然,也還有其它的些手段來(lái)實(shí)現(xiàn)這樣的功能,包括創(chuàng)建去重表、狀態(tài)機(jī)等,都是在應(yīng)用層面或者數(shù)據(jù)庫(kù)層面來(lái)實(shí)現(xiàn),此處不再展開。

          創(chuàng)作不易,煩請(qǐng)點(diǎn)贊分享,感謝!

          鳴謝:
          https://blog.csdn.net/A_art_xiang/article/details/132106309


          推薦閱讀:

          十多年經(jīng)驗(yàn)的老碼農(nóng),竟然倒在了這個(gè)問(wèn)題上:MySQL中的or是否走索引

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

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          96點(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>
                  伊人久久久久亚洲AV无码裤子 | 思思热在线观看视频精品 | 亚洲乱伦视频网址 | 国产精品久久久久久久久免费相片 | 日日夜夜抽麻豆 |