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