佛山網(wǎng)站推廣市場中級經(jīng)濟(jì)師考試
分布式系統(tǒng)接口,如何避免重復(fù)提交
- 1、基于Token的冪等設(shè)計(jì)
- 原理
- 實(shí)現(xiàn)步驟
- 技術(shù)選型
- 2、基于Token的冪等設(shè)計(jì)
- 原理
- 實(shí)現(xiàn)步驟
- 適用場景
- 3、冪等性設(shè)計(jì)
- 原理
- 實(shí)現(xiàn)方式
- 4、分布式鎖
- 原理
- 實(shí)現(xiàn)方式
- 適用場景
- 5、請求去重
- 原理
- 實(shí)現(xiàn)方式
- 6.前端防護(hù)
- 原理
- 實(shí)現(xiàn)方式
- 適用場景
- 7.延遲隊(duì)列
- 原理
- 實(shí)現(xiàn)方式
在分布式系統(tǒng)中,
避免表單重復(fù)提交是一項(xiàng)重要的任務(wù),
尤其是在處理涉及資金交易、訂單創(chuàng)建等敏感業(yè)務(wù)時(shí)。
以下是一些常見的解決方案:
1、基于Token的冪等設(shè)計(jì)
原理
-
在接口請求前,服務(wù)器生成一個(gè)唯一的 Token(可以是 UUID 或其他唯一標(biāo)識),并將其下發(fā)到客戶端。
-
客戶端在請求接口時(shí)攜帶該 Token,服務(wù)器校驗(yàn)該 Token 是否已經(jīng)使用。
a.如果已使用,則拒絕重復(fù)請求。b.如果未使用,則處理請求并將 Token 標(biāo)記為已使用。
實(shí)現(xiàn)步驟
-
生成 Token
a.在用戶訪問接口時(shí),生成一個(gè)唯一的 Token,存儲到 Redis 或數(shù)據(jù)庫中,并返回給客戶端。
-
校驗(yàn) Token
a.接口請求時(shí),服務(wù)器接收到 Token,與存儲的 Token 對比,確保 Token 的唯一性。
-
標(biāo)識 Token
a.請求處理完成后,立即將 Token 標(biāo)記為已使用,避免再次使用。
技術(shù)選型
- 使用 Redis 可以高效處理 Token
- 可以為 Token 設(shè)置 TTL(如 5 分鐘),避免長時(shí)間占用資源。
2、基于Token的冪等設(shè)計(jì)
原理
- 針對業(yè)務(wù)中存在唯一性約束的字段(如訂單編號、交易流水號),在數(shù)據(jù)庫中添加唯一索引。
- 即使分布式系統(tǒng)中有重復(fù)的請求,由于唯一索引的存在,數(shù)據(jù)庫會拒絕重復(fù)寫入。
實(shí)現(xiàn)步驟
- 客戶端生成一個(gè)唯一的業(yè)務(wù)編號(如訂單編號)。
- 服務(wù)端在數(shù)據(jù)庫寫入時(shí),依賴唯一約束來防止重復(fù)提交。
- 如果數(shù)據(jù)庫插入失敗(因唯一約束),則返回錯(cuò)誤提示。
適用場景
- 適用于有明確唯一性標(biāo)識的業(yè)務(wù)場景,例如訂單號、交易號等。
3、冪等性設(shè)計(jì)
原理
- 確保請求的接口是冪等的,即多個(gè)提交的結(jié)果一致
- 常用手段包括狀態(tài)機(jī)和更新操作。
實(shí)現(xiàn)方式
- 狀態(tài)機(jī)
- 更新操作
4、分布式鎖
原理
- 針對同一用戶或同一操作,使用分布式鎖來限制并發(fā)請求的處理。
實(shí)現(xiàn)方式
-
獲取鎖
a.使用 Redis 或 Zookeeper 創(chuàng)建分布式鎖。鎖的 Key 可以是用戶 ID 或業(yè)務(wù) ID。
-
處理請求
a.如果獲取到鎖,則處理請求;如果未獲取到鎖,則直接返回錯(cuò)誤提示。
-
釋放鎖
a.請求處理完成后,釋放分布式鎖。
適用場景
- 避免高并發(fā)場景下的重復(fù)提交。
5、請求去重
原理
- 對于每個(gè)請求,計(jì)算唯一的簽名(如 MD5 或 SHA256),用于標(biāo)識請求內(nèi)容。
- 服務(wù)端根據(jù)簽名判斷請求是否已處理。
實(shí)現(xiàn)方式
1. 生成簽名
a. 基于接口字段內(nèi)容生成簽名,如:
String signature = MD5Utils.generateSignature("接口參數(shù)");
2. 存儲簽名
a. 服務(wù)端存儲簽名,一般是放在 Redis 里邊
3. 校驗(yàn)簽名
a. 適用于接口內(nèi)容較復(fù)雜且需要精確去重的場景。
6.前端防護(hù)
原理
- 利用前端技術(shù)手段,減少重復(fù)提交的可能性。
實(shí)現(xiàn)方式
1.按鈕防重復(fù)點(diǎn)擊:
- 在用戶提交表單后,立即禁用提交按鈕,避免多次點(diǎn)擊。
- 示例:
document.getElementById("submit").disabled = true;
2.表單防回退提交:
- 提交成功后,清空或銷毀表單數(shù)據(jù)。
適用場景
- 適用于用戶誤操作導(dǎo)致的重復(fù)提交,但無法解決惡意重復(fù)提交。
7.延遲隊(duì)列
原理
- 將接口提交請求放入消息隊(duì)列中進(jìn)行處理,系統(tǒng)只接受隊(duì)列中的唯一消息。
實(shí)現(xiàn)方式
1、消息入隊(duì)
- 接口提交時(shí),將請求放入消息隊(duì)列(如 Kafka、RabbitMQ)。
2、消息去重
- 在消息處理階段,服務(wù)端檢查消息 ID 是否已處理。
3、延遲處理
- 設(shè)置延遲隊(duì)列,確保請求在短時(shí)間內(nèi)不會重復(fù)處理。