微服務架構下保證接口的冪等性?
其實在單體服務時代,也會有接口冪等性的問題,只是在分布式、高并發的場景下,接口冪等性的問題會更加明顯一些。那么什么是冪等性?當用戶對同一操作請求了一次或者多次,最終的結果是一致的,并不會因為多次請求產生副作用;比如同一個訂單支付了兩次,最后應該只扣客戶一次錢。
查詢接口具有天然的冪等性(查詢一次還是多次,結果應該都是一樣的),但是在做新增、修改、刪除操作的時候,都要保證冪等性。
全局唯一ID
每一次的請求,都有一個全局唯一的請求ID,這個請求ID只要執行過一次就失效了:
獲得請求ID。
調用接口,同時傳遞請求ID。
交易前判斷請求ID是否存在,如果存在直接返回結果;如果不存在,則執行交易后返回結果,同時記錄請求ID。
許多微服務的架構,生產全局唯一ID都被作為一個基礎的微服務,當然這個微服務的可靠性要求極高,因為這個微服務出現問題,可能會導致很多服務不能工作;所以通常分布式的架構中,會引入全局唯一ID算法。
數據版本號
這種方法適合在更新的場景中,數據中增加版本號的概念,那么在做數據修改,把當前數據的版本號帶上,修改的時候要按照版本號判斷數據是否發生過更改。如果沒有發生過更改,則執行業務操作,并更新版本號。下面的代碼,意會一下:
updateDate(Object obj , int version);
update set obj , version+1 where ...version = 入參version;
狀態機
有些業務流程,每一步都是有狀態的,比如網上購物可能會有:訂單創建、付款、發貨,那么付款之前保單狀態為“待付款”,付款之后可以將保單的狀態修改為“待發貨”;那么如果發起重復扣款的話,第二次扣款的時候保單狀態已經變化了,就會扣款失敗。
去重表
如果業務中有唯一性的標識時,可以使用去重表,把這個唯一性的表示保存到去重表中,如果重復插入,那么會被校驗住。
比如上面的場景,一個訂單只會付款一次,那么在付款的時候,把訂單號作為唯一性的標識,保存到去重表中,可以保證付款操作只會發生一次。
我將持續分享Java開發、架構設計、程序員職業發展等方面的見解,希望能得到你的關注。