天天看點

幂等接口幂等

幂等

帶着以下3個問題來讨論幂等

  1. 什麼是幂等
  2. 什麼時候需要幂等
  3. 怎麼實作幂等

1. 什麼是幂等

  • google Idempotence 得到以下結果 :

    Idempotence is the property of certain operations in mathematics and computer science whereby they can be applied multiple times without changing the result beyond the initial application.

  • 百度裡搜到的一般都是這段的簡單的中文翻譯. 我了解的幂等, 一般是用在對外暴露的接口上, 目的是為了防止重複調用造成資料錯誤處理.
  • 幂等其實我記得最早應該是網絡協定中用到的, 網絡協定中發送封包時, 網絡中經常需要面臨的問題就是網絡逾時, 而逾時的常見處理政策就是重發. 如果用戶端往服務端發送封包逾時了, 可能發送逾時, 服務端沒有收到, 也可能服務端收到了但響應逾時, 隻要服務端是幂等的, 用戶端的重複請求服務方會回應是重複封包, 用戶端就知道已經發送成功了. 這樣就保證了網絡的可靠性設計.

2. 什麼時候需要幂等

幂等是為了保護資料不被重複錯誤處理.

  • 正常資料操作就隻有增删改查, 查詢操作總是幂等的, 是以嚴格來說其他三種操作都要考慮幂等性, 特别是在一些關鍵業務資料, 比如賬戶/金額/訂單交易等等.
  • 對外暴露的接口, 不管是rpc還是http或者是消費上遊發過來的消息,都有可能會有重複的可能. 這時候服務暴露方或者消息消費方都必須設計為幂等的.
  1. http: 使用者重複送出頁面請求, 或者用戶端伺服器逾時重發http請求
  2. rpc : 比如我們常用的dubbo架構, 接口逾時或失敗預設會進行重試 (當然可以設定不重試)
  3. mq消息 : 很多mq消息為了保證可靠性, 如果消息發送端發送逾時, 會嘗試重新發送消息.

3. 怎麼實作幂等

以下幾種常見的也是開發中常用的方案, 其實是在整個服務執行過程的多個不同階段去保證幂等性的, 其實我認為方案很多, 隻要在破壞資料之前校驗都可以的.

    1. 使用者頁面送出請求的時候, 就先進行重複送出的校驗. 常用的方案是采用唯一token生成器, 使用者加載頁面的時候, 會配置設定一個唯一token, 使用者送出的時候會帶着這個token, 我們校驗同一個token是否重複送出了.
    1. 去重表方案, 個人感覺這個方案還是比較實用的, 而且去重表可以設定為分庫分表的, 可以擴充性能. 去重表就是在操作之前,先插入一條記錄, 利用唯一索引防止重複操作, 如果記錄已存在, 接口可以直接傳回已處理, 不要重複操作, 或者直接傳回成功. 與之類似的方案就是利用緩存比如redis來判斷重複.
    1. CAS方案, 可以是要求請求中必須帶有版本号, 利用版本号來CAS更新資料.
    1. 利用資料庫的一緻性, 比如mysql的insert ignore操作和insert on duplicate update等sql, 也能做到保證資料的一緻性.

這些都是我自己常用的, 在這裡簡單總結一下.

繼續閱讀