分布式系统接口幂等性
1.冪等性定義1.1 數(shù)學(xué)定義 在數(shù)學(xué)里,冪等有兩種主要的定義:
1.2 HTTP規(guī)范的定義 在HTTP/1.1規(guī)范中冪等性的定義是: A request method is considered 'idempotent' if the intended effect onthe server of multiple identical requests with that method is the same as the effect for a single such request. Of the request methods defined by this specification, PUT, DELETE, and safe request methods are idempotent. HTTP的冪等性指的是一次和多次請求某一個資源應(yīng)該具有相同的副作用。如通過PUT接口將數(shù)據(jù)的Status置為1,無論是第一次執(zhí)行還是多次執(zhí)行,獲取到的結(jié)果應(yīng)該是相同的,即執(zhí)行完成之后Status =1。 2. 何種接口提供冪等性2.1 HTTP支持冪等性的接口 在HTTP規(guī)范中定義GET,PUT和DELETE方法應(yīng)該具有冪等性。
The GET method requests transfer of a current selected representatiofor the target resourceGET is the primary mechanism of information retrieval and the focus of almost all performance optimizations. Hence, when people speak of retrieving some identifiable information via HTTP, they are generally referring to making a GET request. GET方法是向服務(wù)器查詢,不會對系統(tǒng)產(chǎn)生副作用,具有冪等性(不代表每次請求都是相同的結(jié)果)
T he PUT method requests that the state of the target resource be created or replaced with the state defined by the representation enclosed in the request message payload. 也就是說PUT方法首先判斷系統(tǒng)中是否有相關(guān)的記錄,如果有記錄則更新該記錄,如果沒有則新增記錄。
The DELETE method requests that the origin server remove the association between the target resource and its current functionality. In effect, this method is similar to the rm command in UNIX: it expresses a deletion operation on the URI mapping of the origin server rather than an expectation that the previously associated information be deleted. DELETE方法是刪除服務(wù)器上的相關(guān)記錄。 ? 2.2 實際業(yè)務(wù) 現(xiàn)在簡化為這樣一個系統(tǒng),用戶購買商品的訂單系統(tǒng)與支付系統(tǒng);訂單系統(tǒng)負(fù)責(zé)記錄用戶的購買記錄已經(jīng)訂單的流轉(zhuǎn)狀態(tài)(orderStatus),支付系統(tǒng)用于付款,提供 boolean pay(int accountid,BigDecimal amount) //用于付款,扣除用戶的接口,訂單系統(tǒng)與支付系統(tǒng)通過分布式網(wǎng)絡(luò)交互。 這種情況下,支付系統(tǒng)已經(jīng)扣款,但是訂單系統(tǒng)因為網(wǎng)絡(luò)原因,沒有獲取到確切的結(jié)果,因此訂單系統(tǒng)需要重試。 通過orderId來標(biāo)定訂單的唯一性,付款系統(tǒng)只要檢測到訂單已經(jīng)支付過,則第二次調(diào)用不會扣款而會直接返回結(jié)果:
在不同的業(yè)務(wù)中不同接口需要有不同的冪等性,特別是在分布式系統(tǒng)中,因為網(wǎng)絡(luò)原因而未能得到確定的結(jié)果,往往需要支持接口冪等性。 3.分布式系統(tǒng)接口冪等性隨著分布式系統(tǒng)及微服務(wù)的普及,因為網(wǎng)絡(luò)原因而導(dǎo)致調(diào)用系統(tǒng)未能獲取到確切的結(jié)果從而導(dǎo)致重試,這就需要被調(diào)用系統(tǒng)具有冪等性。 其中value是用戶要減少的訂單,paystatus代表支付狀態(tài),paid代表已經(jīng)支付,unpay代表未支付,orderid是訂單號。 當(dāng)orderStatus 處于0,1兩種狀態(tài)時,對訂單執(zhí)行0->1 的狀態(tài)流轉(zhuǎn)操作應(yīng)該是具有冪等性的。 但是如果此時orderStatus = 2,再進(jìn)行訂單狀態(tài)0->1 時操作就無法成功,但是冪等性是針對同一個請求的,也就是針對同一個requestid保持冪等。 這時候再執(zhí)行 update Order set orderStatus = 1 where OrderId = 'orderid' and orderStatus = 0接口會返回失敗,系統(tǒng)沒有產(chǎn)生修改,如果再發(fā)一次,requestid是相同的,對系統(tǒng)同樣沒有產(chǎn)生修改。 References冪等 |
?
三、如何保證接口的冪等性
接口的冪等性實際上就是接口可重復(fù)調(diào)用,在調(diào)用方多次調(diào)用的情況下,接口最終得到的結(jié)果是一致的。有些接口可以天然的實現(xiàn)冪等性,比如查詢接口,對于查詢來說,你查詢一次和兩次,對于系統(tǒng)來說,沒有任何影響,查出的結(jié)果也是一樣。
除了查詢功能具有天然的冪等性之外,增加、更新、刪除都要保證冪等性。那么如何來保證冪等性呢?
3.1保證冪等策略
冪等需要通過唯一的業(yè)務(wù)單號來保證。也就是說相同的業(yè)務(wù)單號,認(rèn)為是同一筆業(yè)務(wù)。使用這個唯一的業(yè)務(wù)單號來確保,后面多次的相同的業(yè)務(wù)單號的處理邏輯和執(zhí)行效果是一致的。
下面以支付為例,在不考慮并發(fā)的情況下,實現(xiàn)冪等很簡單:①先查詢一下訂單是否已經(jīng)支付過,②如果已經(jīng)支付過,則返回支付成功;如果沒有支付,進(jìn)行支付流程,修改訂單狀態(tài)為‘已支付’。
3.2防重復(fù)提交策略
上述的保證冪等方案是分成兩步的,第②步依賴第①步的查詢結(jié)果,無法保證原子性的。在高并發(fā)下就會出現(xiàn)下面的情況:第二次請求在第一次請求第②步訂單狀態(tài)還沒有修改為‘已支付狀態(tài)’的情況下到來。既然得出了這個結(jié)論,余下的問題也就變得簡單:把查詢和變更狀態(tài)操作加鎖,將并行操作改為串行操作。
列舉三種改進(jìn)方式:
1、悲觀鎖,select for update,整個執(zhí)行過程中鎖定該訂單對應(yīng)的記錄。
2、樂觀鎖,affectrows = db.update(“update payorder set state=’已支付’ where orderid=$orderid and state=’未支付’ “),如果affectrows=1,執(zhí)行充值,否則返回已處理。
3、定義防重復(fù)表,orderid為unique key或者primary key,執(zhí)行前,先insert,若insert成功則執(zhí)行充值,否則返回已處理
總結(jié)
以上是生活随笔為你收集整理的分布式系统接口幂等性的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java 操作Word书签(三):用文本
- 下一篇: 基于ssm的客户管理系统