前言
今年年初遇到項目災難,解決了不少問題,這是其中一個問題。很早的時候寫的,學以緻用的。今天看到還有這樣一篇稿文,那就整理下分享給大家學習!
程式設計思想之幂等性
什麼是幂等性
既然幂等性源于數學,那我就使用數學公式來表示,即可一目了然!
f(f(x)) = f(x)
複制
顯然,從上面的二進制函數可以看出,無論
x
(等幂元素)被函數
y
無限地執行運算,它的結果都是相同的。在計算機程式設計領域中,我們可以這麼定義幂等性:
在調用某個方法、接口中,我們使用相同的參數(相同的特定參數)
,其傳回值都是相同的,我們便可稱方法、接口具有幂等性。從信仰上說,幂等性是一種承諾,隻要一次答應某個承諾,其承諾内容都是不會改變的。
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.
如何了解幂等性
了解性的理論,舉例子掌握最快。
- 無心舉例,看場景更易了解。哈哈
幂等性場景設計
下單處理
這個例子曾經出現在我的身邊:微信服務端在搞事情!
用戶端送出資料超過十秒後,他會定時在十秒後自行斷開并自動再次發起請求,請求的資料體一模一樣,但是這樣的請求是不合法的,屬重複請求。如何解決此事呢?可以使用幂等性作為一個良好的解決方案。為解決此問題,在此先謝謝
騰訊大佬CC
,後會無期!
原本的方法是這樣設計的
function add($userToken, $orderMessage){
//todo
}
複制
這樣處理那就不能規避重複請求了。
基于幂等性來解決此問題,改進的設計方法
function add($seq,$userToken, $orderMessage){
// 現根據seq來判斷是否已經處理過了,是的話就傳回第一次處理的結果
$resultJson = $this->redis->get('***_pre_' . $seq);
if(false != $resultJson){
return $resultJson;
}
// 既然沒有處理過,那就正式處理
// todo
// 處理完了,沒有問題那就将結果儲存起來
// todo
return $resultJson;
}
複制
幂等性
屬于解決此問題的一部分,是解決方案的一部分,還有另一部分是
異步
。
提現
基于幂等性設計 | 防止使用者多次點選(
)或者突然網絡異常等情況下,可以保持資料的一緻性。
後端是不相信前端處理的
兩個步驟:
- 後端生産票據 | 生産隊時給你發糧票,你才有機會拿錢去購買柴米油鹽醬醋茶
- 根據上一步拿到合法的票據來提現
function createTicketSequence($user) : string{
// todo
}
複制
function withdraw($ticketSequence,$user,$amount){
// todo
}
複制
場景了解
1、使用者在取款的時候,用戶端先帶上
請求服務端生成一個合法的取款憑證
token
2、使用者在輸入取款金額并确認取款後,用戶端将會帶上使用者登入憑證
ticketSequeuence
、取款票據
userToken
以及取款金額
ticketSequence
amount
進行請求
3、服務端接收到請求後,先校驗
,校驗失敗則傳回重新登入,否則換取
userToken
4、使用者鑒權通過後,那麼再來校驗取款票據
user對象
ticketSequence
,票據不合法,那麼取款失敗,否則繼續進行取款,一直到取款成功并根據票據作為幂等值來儲存提現成功的結果
5、即使用戶端請求後與服務端失去了聯系,并且服務端處理成功,用戶端處于假死的狀态并再次請求取款,也是傳回第一次的結果,并且是迅速的響應。
價值源于技術,技術源于分享!