日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

高并发下的幂等策略分析

發布時間:2023/12/14 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 高并发下的幂等策略分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
轉載至:http://www.guokr.com/article/47868/?f=wx&page=2


雙十一,零點剛開始,小明就迫不及待地點擊提交訂單按鈕,1秒,2秒,3秒,沒反應,小明有點心慌,又快速地點擊了兩下,提示下單成功。隨后小明到我的訂單列表中一看,發現有三個相同的訂單,小明一臉黑線。

什么是冪等性

HTTP/1.1中對冪等性的定義是:

Methods can also have the property of “idempotence” in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request.

這里不討論學術上如何定義冪等性,而是重點在于如何在分布式環境中提供對外冪等性的接口。對外提供的接口承諾冪等性,其要表達的含義是:只要調用接口成功,外部對接口的多次調用得到的結果是相同的。即執行多次和一次的效果是一樣的。

為什么需要冪等

上面小明遇到的問題,就是在防止重復提交的情況上沒有做好控制。業務開發中,經常會遇到重復提交的情況,無論是由于網絡問題無法收到請求結果而重新發起請求,或是前端的操作抖動而造成重復提交情況。
在交易系統,支付系統這種重復提交造成的問題有尤其明顯,比如:

  • 用戶在APP上連續點擊了多次提交訂單,后臺應該只產生一個訂單;(下多個相同的單,我有病啊)
  • 向支付寶發起支付請求,由于網絡問題或系統BUG重發,支付寶應該只扣一次錢。(多付N筆錢,我真有錢啊)
    很顯然,冪等接口認為,外部調用者會存在多次調用的場景,為了防止重試對數據狀態的改變,需要將接口的設計為冪等的。
  • 什么情況下需要保證冪等性

    以SQL為例,有下面三種場景,只有第三種場景需要開發人員使用其他策略保證冪等性:

  • SELECT col1 FROM tab1 WHER col2=2,無論執行多少次都不會改變狀態,是天然的冪等。
  • UPDATE tab1 SET col1=1 WHERE col2=2,無論執行成功多少次狀態都是一致的,因此也是冪等操作。
  • UPDATE tab1 SET col1=col1+1 WHERE col2=2,每次執行的結果都會發生變化,這種不是冪等的。
  • 保證冪等策略

    冪等需要通過唯一的業務單號來保證。也就是說相同的業務單號,認為是同一筆業務。使用這個唯一的業務單號來確保,后面多次的相同的業務單號的處理邏輯和執行效果是一致的。
    下面以支付為例,在不考慮并發的情況下,實現冪等很簡單:①先查詢一下訂單是否已經支付過,②如果已經支付過,則返回支付成功;如果沒有支付,進行支付流程,修改訂單狀態為‘已支付’。

    防重復提交策略

    上述的保證冪等方案是分成兩步的,第②步依賴第①步的查詢結果,無法保證原子性的。在高并發下就會出現下面的情況:第二次請求在第一次請求第②步訂單狀態還沒有修改為‘已支付狀態’的情況下到來。既然得出了這個結論,余下的問題也就變得簡單:把查詢和變更狀態操作加鎖,將并行操作改為串行操作。

    樂觀鎖

    如果只是更新已有的數據,沒有必要對業務進行加鎖,設計表結構時使用樂觀鎖,一般通過version來做樂觀鎖,這樣既能保證執行效率,又能保證冪等。例如:
    UPDATE tab1 SET col1=1,version=version+1 WHERE version=#version#
    不過,樂觀鎖存在失效的情況,就是常說的ABA問題,不過如果version版本一直是自增的就不會出現ABA的情況。(從網上找了一張圖片很能說明樂觀鎖,引用過來,出自Mybatis對樂觀鎖的支持)

    防重表

    使用訂單號orderNo做為去重表的唯一索引,每次請求都根據訂單號向去重表中插入一條數據。第一次請求查詢訂單支付狀態,當然訂單沒有支付,進行支付操作,無論成功與否,執行完后更新訂單狀態為成功或失敗,刪除去重表中的數據。后續的訂單因為表中唯一索引而插入失敗,則返回操作失敗,直到第一次的請求完成(成功或失敗)。可以看出防重表作用是加鎖的功能。

    分布式鎖

    這里使用的防重表可以使用分布式鎖代替,比如Redis。訂單發起支付請求,支付系統會去Redis緩存中查詢是否存在該訂單號的Key,如果不存在,則向Redis增加Key為訂單號。查詢訂單支付已經支付,如果沒有則進行支付,支付完成后刪除該訂單號的Key。通過Redis做到了分布式鎖,只有這次訂單訂單支付請求完成,下次請求才能進來。相比去重表,將放并發做到了緩存中,較為高效。思路相同,同一時間只能完成一次支付請求

    token令牌

    這種方式分成兩個階段:申請token階段和支付階段。
    第一階段,在進入到提交訂單頁面之前,需要訂單系統根據用戶信息向支付系統發起一次申請token的請求,支付系統將token保存到Redis緩存中,為第二階段支付使用。
    第二階段,訂單系統拿著申請到的token發起支付請求,支付系統會檢查Redis中是否存在該token,如果存在,表示第一次發起支付請求,刪除緩存中token后開始支付邏輯處理;如果緩存中不存在,表示非法請求。
    實際上這里的token是一個信物,支付系統根據token確認,你是你媽的孩子。不足是需要系統間交互兩次,流程較上述方法復雜。

    支付緩沖區

    把訂單的支付請求都快速地接下來,一個快速接單的緩沖管道。后續使用異步任務處理管道中的數據,過濾掉重復的待支付訂單。
    優點是同步轉異步,高吞吐。不足是不能及時地返回支付結果,需要后續監聽支付結果的異步返回。

    冪等性接口的不足

  • 增加了額外控制冪等的業務邏輯,復雜化了業務功能;
  • 把并行執行的功能改為串行執行,降低了執行效率。
    因此除了業務上的特殊要求外,盡量不提供冪等的接口。

  • 總結

    以上是生活随笔為你收集整理的高并发下的幂等策略分析的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。