最近很多人都在談?wù)搩绲刃?,好吧,這回我也來聊聊這個話題,光看著倆字,一開始的確有點一頭霧水,語文不好嘛,詞太專業(yè)嘛,對吧 現(xiàn)如今我們的系統(tǒng)大多拆分為分布式SOA,或者微服務(wù),一套系統(tǒng)中包含了多個子系統(tǒng)服務(wù),而一個子系統(tǒng)服務(wù)往往會去調(diào)用另一個服務(wù),而服務(wù)調(diào)用服務(wù)無非就是使用RPC通信或者restful,既然是通信,那么就有可能再服務(wù)器處理完畢后返回結(jié)果的時候掛掉,這個時候用戶端發(fā)現(xiàn)很久沒有反應(yīng),那么就會多次點擊按鈕,這樣請求有多次,那么處理數(shù)據(jù)的結(jié)果是否要統(tǒng)一呢?那是肯定的!尤其再支付場景。 冪等性:就是用戶對于同一操作發(fā)起的一次請求或者多次請求的結(jié)果是一致的,不會因為多次點擊而產(chǎn)生了副作用。舉個最簡單的例子,那就是支付,用戶購買商品使用約支付,支付扣款成功,但是返回結(jié)果的時候網(wǎng)絡(luò)異常,此時錢已經(jīng)扣了,用戶再次點擊按鈕,此時會進(jìn)行第二次扣款,返回結(jié)果成功,用戶查詢余額返發(fā)現(xiàn)多扣錢了,流水記錄也變成了兩條... 在以前的單應(yīng)用系統(tǒng)中,我們只需要把數(shù)據(jù)操作放入事務(wù)中即可,發(fā)生錯誤立即回滾,但是再響應(yīng)客戶端的時候也有可能出現(xiàn)網(wǎng)絡(luò)中斷或者異常等等。 在增刪改查4個操作中,尤為注意就是增加或者修改, 查詢對于結(jié)果是不會有改變的, 刪除只會進(jìn)行一次,用戶多次點擊產(chǎn)生的結(jié)果一樣 修改在大多場景下結(jié)果一樣 增加在重復(fù)提交的場景下會出現(xiàn) 那么如何設(shè)計接口才能做到冪等呢? 方法一、單次支付請求,也就是直接支付了,不需要額外的數(shù)據(jù)庫操作了,這個時候發(fā)起異步請求創(chuàng)建一個唯一的ticketId,就是門票,這張門票只能使用一次就作廢,具體步驟如下:
如果步驟4通信失敗,用戶再次發(fā)起請求,那么最終結(jié)果還是一樣的 方法二、分布式環(huán)境下各個服務(wù)相互調(diào)用 這邊就要舉例我們的系統(tǒng)了,我們支付的時候先要扣款,然后更新訂單,這個地方就涉及到了訂單服務(wù)以及支付服務(wù)了。 用戶調(diào)用支付,扣款成功后,更新對應(yīng)訂單狀態(tài),然后再保存流水。 而在這個地方就沒必要使用門票ticketId了,因為會比較閑的麻煩 (支付狀態(tài):未支付,已支付) 步驟: 1、查詢訂單支付狀態(tài) select for update 2、如果已經(jīng)支付,直接返回結(jié)果 3、如果未支付,則支付扣款并且保存流水 4、返回支付結(jié)果 如果步驟4通信失敗,用戶再次發(fā)起請求,那么最終結(jié)果還是一樣的 對于做過支付的朋友,冪等,也可以稱之為沖正,保證客戶端與服務(wù)端的交易一致性,避免多次扣款。 最后來看一下我們的訂單流程,雖然不是很復(fù)雜,但是最后在支付環(huán)境是一定要實現(xiàn)冪等性的
|
|