分佈式高併發系統如何保證對外接口的冪等性?

牛牛愛妞牛

高併發系統不做冪等很有可能造成嚴重的生產事故!

以我自身為例,有一次編寫一個扣錢接口,然後調用的時候扣了用戶兩次錢,直接被投訴了,最後公司兩倍賠了客戶,才算了結,雖然老闆一直安慰我這種事很正常,但是從查到問題那一刻開始,心裡還是不好受的!


言歸正傳,先看下接口冪等性是啥?就是同一個接口,同樣的參數在多次調用時,起到的作用是一樣的!不會有別的副作用!

那一個接口做的操作無外乎增刪改查,我們來分別討論下場景:

1,查數據:天然的冪等性,不會對數據造成影響!

2,改數據:

①,改到固定數據:比如說改操作人到某人,狀態改為啥,這樣的操作無論多少次也不會對數據有影響!

3,刪除數據:多次刪除有可能有sql異常,幾無數據影響

4,新增數據:一下子增加了好幾條重複數據,有冪等影響

能看到實際業務中,接口重複性的可能性還是有很多的,解決冪等的方案有哪些呢?

1,如果是刪除,可以先查再刪,保證數據存在,不會有sql異常拋出!

2,如果是修改,可以增加版本標誌,比如說在頁面查詢的時候版本還是1,經過更改提交之後瘋狂的提交了多次,然後有一個調用先生效,版本變為了2,這時候雖然版本還為1的sql過來了,不允許再做修改!避免了多次修改!


3,如果是新增,可以增加全局唯一性ID,然後在數據庫添加唯一索引,在點擊新增按鈕的時候把ID返回給調用端,填寫新增數據後提交,使用這個ID查詢是否有了數據,如果有則不會再新增,就算不做此操作,數據庫也會拋出重複key異常!保證數據只插入一條!

可以說接口重複提交很有可能造成數據安全問題,給公司或者自己造成損失,一定要極力避免!

更多JAVA實際編程中的技術分享,敬請關注。。。


謝逅架構

概念

首先來看看什麼是冪等性:用戶對同一操作請求了一次或者多次,最終的結果是一致的,並不會因為多次請求產生副作用。

比如客戶在網頁上購買商品後付款的時候,點擊了付款,支付成功已經扣款,但是由於網絡的原因導致扣款成功的提示沒有顯示在頁面上。這時候客戶認為付款失敗,於是又點擊了付款,結果第二次付款也成功了。那麼這樣就是有問題的。


分佈式系統接口冪等

所有的接口操作,不外乎就是增刪查改。

查詢和刪除操作,天然的具有冪等的特性:

  • 查詢:數據不變的情況下,查詢一次和查詢多次的結果都是一樣的。

  • 刪除:刪除一次和刪除多次,結果都是一樣的。


而新增和修改,如果不做冪等性處理,可能就會產生問題。


如何保證接口的冪等性

方案一,每一次的請求,都有一個全局唯一的請求ID,這個請求ID只要執行過一次就失效了:

  • 獲得請求ID。

  • 調用接口,同時傳遞請求ID。

  • 交易前判斷請求ID是否存在,如果存在直接返回結果;如果不存在,則執行交易後返回結果,同時記錄請求ID。


方案二,數據中增加版本號的概念,那麼在做數據修改,把當前數據的版本號帶上,修改的時候要按照版本號判斷數據是否發生過更改。如果沒有發生過更改,則執行業務操作,並更新版本號。翻譯成偽代碼就是:

if(數據version == 請求傳過來的version){

執行業務操作();

version = version + 1;

}else{

提示執行失敗();

}


希望我的回答能夠幫助到你!


會點代碼的大叔

接口冪等性可以保證多次請求產生的最終結果是一致的,也就是沒處理過的執行處理操作,處理過的終止執行。可以通過檢查數據狀態位是否為終態或判斷全局中是否有對應可執行標識來進行冪等設計。

希望對你有所幫助!


分享到:


相關文章: