分散式系統中的冪等性和非冪
一.簡介
現如今系統大多為分散式SOA或者微服務,一套系統中包含多個子系統,子系統之間互相呼叫。
而服務呼叫服務無非就是使用RPC通訊或者restful,既然是通訊,那麼就有可能在伺服器處理完畢後返回結果的時候掛掉,這個時候使用者端發現很久沒有反應,那麼就會多次點選按鈕,這樣請求有多次,那麼處理資料的結果是否要統一呢?那是肯定的!尤其在支付場景。
冪等性:就是使用者對於同一操作發起的一次請求或者多次請求的結果是一致的,不會因為多次點選而產生了副作用。
非冪性:在這種情況下,如果出現多個客戶端操作共享資源,就可能意味著資料不一致,資料丟失。
二.舉例
舉個最簡單的例子,那就是支付,使用者購買商品支付購買,支付扣款成功,但是返回結果的時候網路異常,此時錢已經扣了,使用者再次點選按鈕,此時會進行第二次扣款,返回結果成功,使用者查詢餘額返發現多扣錢了,流水記錄也變成了兩條。
在以前的單應用系統中,我們只需要把資料操作放入事務中即可,發生錯誤立即回滾,但是再響應客戶端的時候也有可能出現網路中斷或者異常等等。
三.冪等性設定
操作分析
在增刪改查4個操作中,尤為注意就是增加或者修改
查詢對於結果是不會有改變的
刪除只會進行一次,使用者多次點選產生的結果一樣
修改在大多場景下結果一樣
增加在重複提交的場景下會出現
方法一:門票
單次支付請求,也就是直接支付了,不需要額外的資料庫操作了,這個時候發起非同步請求建立一個唯一的ticketId,就是門票,這張門票只能使用一次就作廢,具體步驟如下:
非同步請求獲取門票
呼叫支付,傳入門票
根據門票ID查詢此次操作是否存在,如果存在則表示該操作已經執行過,直接返回結果;如果不存在,支付扣款,儲存結果
返回結果到客戶端
如果步驟4通訊失敗,使用者再次發起請求,那麼最終結果還是一樣的
方法二:訂單狀態
這邊就要舉例我們的系統了,我們支付的時候先要扣款,然後更新訂單,這個地方就涉及到了訂單服務以及支付服務了。
1、查詢訂單支付狀態(未支付,已支付)
2、如果已經支付,直接返回結果
3、如果未支付,則支付扣款並且儲存流水
4、返回支付結果
如果步驟4通訊失敗,使用者再次發起請求,那麼最終結果還是一樣的
本文版權歸作者所有,歡迎轉載,請務必新增原文連結。