前言
今年年初遇到項目災(zāi)難,解決了不少問題拴鸵,這是其中一個問題。很早的時候?qū)懙奈仙Γ瑢W(xué)以致用的劲藐。今天看到還有這樣一篇稿文,那就整理下分享給大家學(xué)習(xí)樟凄!編程思想之冪等性
什么是冪等性
既然冪等性源于數(shù)學(xué)聘芜,那我就使用數(shù)學(xué)公式來表示,即可一目了然缝龄!
f(f(x)) = f(x)
顯然汰现,從上面的二元函數(shù)可以看出挂谍,無論x
(等冪元素)被函數(shù)y
無限地執(zhí)行運算,它的結(jié)果都是相同的瞎饲。在計算機編程領(lǐng)域中口叙,我們可以這么定義冪等性:在調(diào)用某個方法、接口中嗅战,我們使用相同的參數(shù)(相同的特定參數(shù))
妄田,其返回值都是相同的,我們便可稱方法驮捍、接口具有冪等性疟呐。從信仰上說,冪等性是一種承諾东且,只要一次答應(yīng)某個承諾萨醒,其承諾內(nèi)容都是不會改變的。
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.
如何理解冪等性
理解性的理論苇倡,舉例子掌握最快富纸。
- 無心舉例,看場景更易理解旨椒。哈哈
冪等性場景設(shè)計
下單處理
這個例子曾經(jīng)出現(xiàn)在我的身邊:微信服務(wù)端在搞事情晓褪!
客戶端提交數(shù)據(jù)超過十秒后,他會定時在十秒后自行斷開并自動再次發(fā)起請求综慎,請求的數(shù)據(jù)體一模一樣涣仿,但是這樣的請求是不合法的,屬重復(fù)請求示惊。如何解決此事呢好港?可以使用冪等性作為一個良好的解決方案。為解決此問題米罚,在此先謝謝騰訊大佬CC
,后會無期钧汹!
原本的方法是這樣設(shè)計的
function add($userToken, $orderMessage){
//todo
}
這樣處理那就不能規(guī)避重復(fù)請求了。
基于冪等性來解決此問題录择,改進的設(shè)計方法
function add($seq,$userToken, $orderMessage){
// 現(xiàn)根據(jù)seq來判斷是否已經(jīng)處理過了拔莱,是的話就返回第一次處理的結(jié)果
$resultJson = $this->redis->get('***_pre_' . $seq);
if(false != $resultJson){
return $resultJson;
}
// 既然沒有處理過,那就正式處理
// todo
// 處理完了隘竭,沒有問題那就將結(jié)果保存起來
// todo
return $resultJson;
}
冪等性
屬于解決此問題的一部分塘秦,是解決方案的一部分,還有另一部分是異步
动看。
提現(xiàn)
基于冪等性設(shè)計 | 防止用戶多次點擊(后端是不相信前端處理的
)或者突然網(wǎng)絡(luò)異常等情況下尊剔,可以保持數(shù)據(jù)的一致性。
兩個步驟:
- 后端生產(chǎn)票據(jù) | 生產(chǎn)隊時給你發(fā)糧票菱皆,你才有機會拿錢去購買柴米油鹽醬醋茶
- 根據(jù)上一步拿到合法的票據(jù)來提現(xiàn)
function createTicketSequence($user) : string{
// todo
}
function withdraw($ticketSequence,$user,$amount){
// todo
}
場景理解
1须误、用戶在取款的時候笔咽,客戶端先帶上token
請求服務(wù)端生成一個合法的取款憑證ticketSequeuence
2、用戶在輸入取款金額并確認取款后霹期,客戶端將會帶上用戶登錄憑證userToken
叶组、取款票據(jù)ticketSequence
以及取款金額amount
進行請求
3、服務(wù)端接收到請求后历造,先校驗userToken
甩十,校驗失敗則返回重新登錄,否則換取user對象
4吭产、用戶鑒權(quán)通過后侣监,那么再來校驗取款票據(jù)ticketSequence
,票據(jù)不合法臣淤,那么取款失敗橄霉,否則繼續(xù)進行取款,一直到取款成功并根據(jù)票據(jù)作為冪等值來保存提現(xiàn)成功的結(jié)果
5邑蒋、即使客戶端請求后與服務(wù)端失去了聯(lián)系姓蜂,并且服務(wù)端處理成功,客戶端處于假死的狀態(tài)并再次請求取款医吊,也是返回第一次的結(jié)果钱慢,并且是迅速的響應(yīng)。