日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

分布式系统接口幂等性

發布時間:2023/12/14 windows 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 分布式系统接口幂等性 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
  • 1.冪等性定義
    • 1.1 數學定義
    • 1.2 HTTP規范的定義
  • 2. 何種接口提供冪等性
    • 2.1 HTTP支持冪等性的接口
    • 2.2 實際業務
  • 3.分布式系統接口冪等性
  • References

1.冪等性定義

1.1 數學定義

在數學里,冪等有兩種主要的定義:

  • 在某二元運算下,冪等元素是指被自己重復運算(或對于函數是為復合)的結果等于它自己的元素。例如,乘法下唯一兩個冪等實數為0和1。 即 s *s = s
  • 某一元運算為冪等的時,其作用在任一元素兩次后會和其作用一次的結果相同。例如,高斯符號便是冪等的,即f(f(x)) = f(x)。

1.2 HTTP規范的定義

在HTTP/1.1規范中冪等性的定義是:

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的冪等性指的是一次和多次請求某一個資源應該具有相同的副作用。如通過PUT接口將數據的Status置為1,無論是第一次執行還是多次執行,獲取到的結果應該是相同的,即執行完成之后Status =1。

2. 何種接口提供冪等性

2.1 HTTP支持冪等性的接口

在HTTP規范中定義GET,PUT和DELETE方法應該具有冪等性。

  • GET方法

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方法是向服務器查詢,不會對系統產生副作用,具有冪等性(不代表每次請求都是相同的結果)

  • PUT方法

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方法首先判斷系統中是否有相關的記錄,如果有記錄則更新該記錄,如果沒有則新增記錄。

  • DELETE 方法

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方法是刪除服務器上的相關記錄。

?

2.2 實際業務

現在簡化為這樣一個系統,用戶購買商品的訂單系統與支付系統;訂單系統負責記錄用戶的購買記錄已經訂單的流轉狀態(orderStatus),支付系統用于付款,提供

boolean pay(int accountid,BigDecimal amount) //用于付款,扣除用戶的

接口,訂單系統與支付系統通過分布式網絡交互。

這種情況下,支付系統已經扣款,但是訂單系統因為網絡原因,沒有獲取到確切的結果,因此訂單系統需要重試。
由上圖可見,支付系統并沒有做到接口的冪等性,訂單系統第一次調用和第二次調用,用戶分別被扣了兩次錢,不符合冪等性原則(同一個訂單,無論是調用了多少次,用戶都只會扣款一次)。
如果需要支持冪等性,付款接口需要修改為以下接口:

boolean pay(int orderId,int accountId,BigDecimal amount)

通過orderId來標定訂單的唯一性,付款系統只要檢測到訂單已經支付過,則第二次調用不會扣款而會直接返回結果:

在不同的業務中不同接口需要有不同的冪等性,特別是在分布式系統中,因為網絡原因而未能得到確定的結果,往往需要支持接口冪等性。

3.分布式系統接口冪等性

隨著分布式系統及微服務的普及,因為網絡原因而導致調用系統未能獲取到確切的結果從而導致重試,這就需要被調用系統具有冪等性。
例如上文所闡述的支付系統,針對同一個訂單保證支付的冪等性,一旦訂單的支付狀態確定之后,以后的操作都會返回相同的結果,對用戶的扣款也只會有一次。這種接口的冪等性,簡化到數據層面的操作:

update userAmount set amount = amount - 'value' ,paystatus = 'paid' where orderId= 'orderid' and paystatus = 'unpay'

其中value是用戶要減少的訂單,paystatus代表支付狀態,paid代表已經支付,unpay代表未支付,orderid是訂單號。
在上文中提到的訂單系統,訂單具有自己的狀態(orderStatus),訂單狀態存在一定的流轉。訂單首先有提交(0),付款中(1),付款成功(2),付款失敗(3),簡化之后其流轉路徑如圖:

當orderStatus = 1 時,其前置狀態只能是0,也就是說將orderStatus由0->1 是需要冪等性的

update Order set orderStatus = 1 where OrderId = 'orderid' and orderStatus = 0

當orderStatus 處于0,1兩種狀態時,對訂單執行0->1 的狀態流轉操作應該是具有冪等性的。
這時候需要在執行update操作之前檢測orderStatus是否已經=1,如果已經=1則直接返回true即可。

但是如果此時orderStatus = 2,再進行訂單狀態0->1 時操作就無法成功,但是冪等性是針對同一個請求的,也就是針對同一個requestid保持冪等。

這時候再執行

update Order set orderStatus = 1 where OrderId = 'orderid' and orderStatus = 0

接口會返回失敗,系統沒有產生修改,如果再發一次,requestid是相同的,對系統同樣沒有產生修改。

References

冪等
HTTP冪等性概念和應用
What Is Idempotent in REST?
REST之中的冪等指的是什么?
Hypertext Transfer Protocol (HTTP/1.1)

?

三、如何保證接口的冪等性

接口的冪等性實際上就是接口可重復調用,在調用方多次調用的情況下,接口最終得到的結果是一致的。有些接口可以天然的實現冪等性,比如查詢接口,對于查詢來說,你查詢一次和兩次,對于系統來說,沒有任何影響,查出的結果也是一樣。

除了查詢功能具有天然的冪等性之外,增加、更新、刪除都要保證冪等性。那么如何來保證冪等性呢?

3.1保證冪等策略

冪等需要通過唯一的業務單號來保證。也就是說相同的業務單號,認為是同一筆業務。使用這個唯一的業務單號來確保,后面多次的相同的業務單號的處理邏輯和執行效果是一致的。
下面以支付為例,在不考慮并發的情況下,實現冪等很簡單:①先查詢一下訂單是否已經支付過,②如果已經支付過,則返回支付成功;如果沒有支付,進行支付流程,修改訂單狀態為‘已支付’。

3.2防重復提交策略

上述的保證冪等方案是分成兩步的,第②步依賴第①步的查詢結果,無法保證原子性的。在高并發下就會出現下面的情況:第二次請求在第一次請求第②步訂單狀態還沒有修改為‘已支付狀態’的情況下到來。既然得出了這個結論,余下的問題也就變得簡單:把查詢和變更狀態操作加鎖,將并行操作改為串行操作。

列舉三種改進方式:

1、悲觀鎖,select for update,整個執行過程中鎖定該訂單對應的記錄。

2、樂觀鎖,affectrows = db.update(“update payorder set state=’已支付’ where orderid=$orderid and state=’未支付’ “),如果affectrows=1,執行充值,否則返回已處理。

3、定義防重復表,orderid為unique key或者primary key,執行前,先insert,若insert成功則執行充值,否則返回已處理

總結

以上是生活随笔為你收集整理的分布式系统接口幂等性的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。