1.背景
最近的系統中使用了springcloud微服務框架,這種分布式框架的確提供了非常多便利的地方,不過隨之也出現了很多的問題,特別是在實際開發中,介面的冪等性。
而所謂的冪等,通俗點說就是乙個操作不管請求多少次返回的結果都是一樣的,比如支付、扣除庫存、扣除積分等等,如果因為網路問題而出現多扣、多加、多新增資料的問題,
不僅會影響使用者體驗,資料的維護也非常的困難。
2.概念
冪等:在程式設計中乙個冪等操作中任意多次執行產生的影響均與一次執行的影響相同。冪等函式或者方法,是指可以使用相引數重複執行,並能獲取相同結果的函式。這些函式不會影響系統狀態。
3.具體實現
a)、增加唯一索引
就比如乙個使用者簽到贈送積分的場景,使用者進入程式的首頁就觸發簽到程式,主動給使用者簽到,並且贈送積分。但是由於網路的問題,前端同乙個使用者的簽到觸發了兩次請求,積分也贈送了兩次。
程式的初始也做了一些基本的重複簽到處理,如select + insert,查詢某使用者是否簽到過,然後再進行簽到。雖然能簡單有效的控制重複簽到的問題,但是高併發的情況下,而且是在分布式框架中,select + insert 就顯得非常的無力。那麼唯一索引就非常好的解決了這個問題。設計簽到表時,把使用者的id和簽到日期作為表的聯合唯一主鍵,這樣簽到表中無論什麼情況下只可能存在一條簽到資料,積分也可能贈送一次。
b)、樂觀鎖和悲觀鎖
樂觀鎖和悲觀鎖通常也用於資料重複多次提交、併發刪除更新等問題。
詳情可看文章:
c)、token機制,前端防止重複提交
資料提交前向伺服器申請token,token放到redis中,提交後後台校驗token,同時刪除tonken,保證了每個請求只有乙個tonken。
不過要注意的點是,這種方式通過刪除token結果來校驗token的正確性。
如果刪除前加了查詢(select)再刪除來校驗token,那麼又會引發併發問題,存在隱患。
d)、分布式鎖
目前分布式鎖的實現可以借助第三方的工具實現,快取(redis)、zookeeper,也可以基於資料庫實現分布式鎖。
那麼分布式鎖會加入考慮中,必然要保證在專案集群中,獲取鎖和釋放鎖的效能要好,而且要避免死鎖。
參考文章:
如何保證分布式系統介面冪等?
這是實戰經常遇到的乙個問題,舉個例子 我們系統的開票介面受理對方系統的報文 結算單號settleno 開票單號ticketno 由於網路抖動或者前端提交多次導致同一筆重複請求,如果不設定冪等,我們系統就會受理多筆相同的請求,最終可能導致多次重複開票的問題。所以我們要保證介面冪等,使得重複請求只會成功...
分布式系統的介面冪等性設計
在微服務架構下,我們在完成乙個訂單流程時經常遇到下面的場景 乙個訂單建立介面,第一次呼叫超時了,然後呼叫方重試了一次 在訂單建立時,我們需要去扣減庫存,這時介面發生了超時,呼叫方重試了一次 當這筆訂單開始支付,在支付請求發出之後,在服務端發生了扣錢操作,介面響應超時了,呼叫方重試了一次 乙個訂單狀態...
分布式介面的冪等設計
什麼是介面的冪等性,介面的冪等性實際上就是介面可重複呼叫,在呼叫方多次呼叫的情況下,介面最終得到的結果是一致的。有些介面可以天然的實現冪等性,比如查詢介面,對於查詢來說,你查詢一次和兩次,對於系統來說,沒有任何影響,查出的結果也是一樣。除了查詢功能具有天然的冪等性之外,增加 更新 刪除都要保證冪等性...