在業(yè)務(wù)設(shè)計(jì)中防重設(shè)計(jì)是一個(gè)關(guān)鍵點(diǎn),以接口設(shè)計(jì)為例,防重就是防止接口被多次調(diào)用而產(chǎn)生臟數(shù)據(jù),比如支付訂單出現(xiàn)重復(fù)支付,所以說防重至關(guān)重要,在如何防重之前我們首先看一下是如何出現(xiàn)重復(fù)請(qǐng)求的。
何時(shí)出現(xiàn)多次調(diào)用。
多次調(diào)用接口的出現(xiàn)有主觀原因比如:人為的重復(fù)請(qǐng)求攻擊,用戶的誤操作等;也有客觀原因比如:為了健壯性進(jìn)行超時(shí)重試;
- 重復(fù)請(qǐng)求攻擊。
對(duì)于這種惡意攻擊,其實(shí)已經(jīng)屬于安全范疇了,我們可以通過黑名單 + 限流來處理,下一步再考慮防重處理。
- 用戶的誤操作。
比如用戶在界面點(diǎn)擊提交按鈕,因?yàn)槭终`出現(xiàn)多次點(diǎn)擊提交,這種情況客戶端可以做一些處理,減少用戶的誤操作,比如提交完按鈕變灰等;當(dāng)然提供方的防重處理也是必不可少的。
- 超時(shí)重試。
接口調(diào)用方為了保證系統(tǒng)的健壯性,往往會(huì)做一些重試處理,比如各種 RPC 框架都已經(jīng)幫我們內(nèi)置了容錯(cuò)機(jī)制,提供方需要做好防重。
如何做好防重處理,其實(shí)核心就是保證多個(gè)相同的請(qǐng)求只有一次被執(zhí)行,或者說多次調(diào)用和一次調(diào)用產(chǎn)生的效果是一樣的,也就是我們經(jīng)常說的要保證冪等性。
何時(shí)需要防重。
所有的操作說到底都是增刪改查,其實(shí)我們真正需要做防重處理的,更重要的是增加和修改;查詢和刪除本身執(zhí)行一次和多次,產(chǎn)生的效果是一樣的,有天然冪等性,雖然說有天然冪等性,但是查詢和刪除本身也是要消耗資源的,如果能防止重復(fù)執(zhí)行,也能節(jié)省資源。
增加和修改是必須要做防重的,增加可以以下單為例,修改可以以更新庫存為例,如果沒有做好防重后果是非常嚴(yán)重的;下面具體看看都有哪些防重的措施。
如何防重?
上面說到主要是針對(duì)增加和修改需要做好防重處理,當(dāng)然針對(duì)增加和修改其實(shí)是有不同的防重措施,也有統(tǒng)一的方式,下面分別介紹:
統(tǒng)一防重。
- token 機(jī)制。
服務(wù)器需要提供獲取 token 機(jī)制的服務(wù),這樣每次客戶端請(qǐng)求的時(shí)候先獲取 token,服務(wù)器端會(huì)將 token 保存在 redis 中;客戶端發(fā)送請(qǐng)求的時(shí)候會(huì)帶上 token,這樣服務(wù)器端可以拿到 token 直接去 redis 中做刪除處理,根據(jù)返回值判斷是否成功。
- 防重表。
可以利用表的唯一索引約束,可以使用類似防重 key 作為唯一索引字段,多次請(qǐng)求過來只會(huì)有一個(gè)插入成功,為了防止防重表數(shù)據(jù)過多,可以啟動(dòng)一個(gè)定時(shí)器定時(shí)清理;
以上幾種方式其實(shí)和具體的業(yè)務(wù)關(guān)系不大,可以適用大部分場(chǎng)景;而且通過 redis 或者數(shù)據(jù)庫,以及原子性操作來保證在分布式環(huán)境下也可以很好的運(yùn)行;
插入防重。
- select+insert。
插入數(shù)據(jù)最先想到就是先檢查有沒有,然后再插入,但是這樣明顯存在兩個(gè)操作,不是原子性操作,單節(jié)點(diǎn)下還能通過鎖來解決,分布式環(huán)境下就需要用到分布式鎖來保證原子性了;當(dāng)然也可以結(jié)合其他方式一起使用,比如下面的唯一主鍵機(jī)制。
- 唯一主鍵。
這種方式其實(shí)就是不直接使用數(shù)據(jù)庫的自增主鍵了,使用分布式 id 算法生成,這樣在插入數(shù)據(jù)的時(shí)候就可以通過唯一主鍵來進(jìn)行約束,保證只會(huì)有一條成功。
- 回滾機(jī)制。
有些業(yè)務(wù)其實(shí)是有正向流程和逆向流程,比如支付訂單,在接收到銀行返回的支付成功通知時(shí)判斷訂單的狀態(tài),如果已經(jīng)支付成功,可以直接走退款流程。
防重的方法很多,我們往往需要更加自己的業(yè)務(wù)做相關(guān)的選擇,不同的業(yè)務(wù),不同的業(yè)務(wù)量,不同的容忍程度都會(huì)影響我們?nèi)绾稳プ龇乐兀幻糠N方式也不是都是獨(dú)立存在的,有時(shí)候往往需要多種方式整合起來。

熱門跟貼