工作中的點點滴滴-接口冪等的問題

 

背景

  最近上線了一套官網的大客戶運營系統,其中有個功能是運營人員可以直接通過這個平臺給客戶下單,生成好的訂單,再讓高級權限人員審覈,我們再通過訂單系統接口推送給訂單系統進行生成履約等環節。訂單接口返回成功,我們會把我們系統的訂單狀態標記爲“生產中”,訂單接口返回失敗我們標記爲“生產失敗”。然後在上線運行的時候發現了一個問題就是有一個訂單,是明明已經推送給了訂單系統中,但是在我們這邊顯示的“生產失敗”。然後通過日誌信息發現,這筆訂單調用了兩次訂單系統的接口,第一次調用成功,訂單標記爲“生產中”,第二次調用失敗,訂單系統返回當前訂單已經存在,然後我們系統判斷調用失敗,訂單標記爲“生產失敗”。然後追蹤原因發現訂單那審覈接口調用了兩次,導致了這個問題的產生。至於爲什麼會調用兩次這裏就不再追究。通過這個問題我們發現同一個業務單據調用同一個接口如果要保證結果的一致,那麼這個接口就需要做冪等,查看百度百科上對冪等的定義其實基本上也和這個差不多。

  當然上面我遇到的這個場景除外,比如像訂單支付,同一個訂單支付多次,然後多次扣款,那客戶還不提着50m大刀趕過來了呀。另外一種常見的場景就是Mq消息在消費的時候遇到重複消費的場景,像這種情況也是需要做接口冪等的,要不然數據肯定會有髒數據問題了。

保證冪等性的幾種方式

  • 對於新增訂單這種類似的接口。前端連續多次點擊提交按鈕瘋狂的調用新建訂單接口,像這種情況就可以使用接口參上加上token的機制來實現防止數據接口重複提交。最簡單直接的實現方式就是在提交訂單接口前面調用獲取一次token,在獲取token的服務端接口裏面生成token的同時還需要把這個token給保存起來,然後客戶端在調用新建訂單接口的時候帶上這個token來訪問,服務端獲取到這個token,判斷一下這個token是否存在,如果存在則表示第一次提交,放行請求,並且刪掉這個token。相反的,如果token不存在,就代表是重複請求,不需要進行業務處理,返回給前端一個重複的標記即可。

  • 對於新增數據的這種情況,還可以通過數據庫的唯一性索引來處理。防止數據重複提交。

  • 針對像上面我遇到的那種場景是數據修改數據的情況,類似這種的,可以使用狀態機來保住接口冪等性。就用我們那個訂單例子,他的流程就有創建中,創建完成,待審批,生產中,生成完成,生產失敗等,生產中的前置狀態那麼只能是待審批,生產失敗的前置狀態也只能是待審批,就是說這個訂單如果想變成生產失敗,那麼它就只能從待審批這個狀態過來。所以通過這種狀態機的流轉我們就可以控制請求的冪等。

  • 像MQ這種重複消費的情況,一般在使用mq的業務場景,我們都保存一下mq消息的唯一key,然後把這個唯一key存在數據或者redis裏面,在消費的業務處理方法裏面判斷一下這個消息key是否存在,如果已經存在,就表示已經消費過了 ,相反的就表示可以正常放行處理。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章