Distributed system interface idempotency (transfer)

1. Definition of idempotency

1.1 Mathematical Definition

In mathematics, there are two main definitions of idempotency:

  • Under a binary operation, an idempotent element is one whose result is equal to its own element repeated by itself (or composite for functions). For example, the only two idempotent real numbers under multiplication are 0 and 1. i.e. s*s = s
  • When an element operation is idempotent, its effect on any element twice will be the same as if it were applied once. For example, Gaussian notation is idempotent, i.e. f(f(x)) = f(x).

1.2 Definition of HTTP Specification

The definition of idempotency in the HTTP/1.1 specification is:

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.

The idempotency of HTTP means that one and multiple requests for a resource should have the same side effects. If the Status of the data is set to 1 through the PUT interface, whether it is the first execution or multiple executions, the obtained result should be the same, that is, Status = 1 after the execution is completed.

2. Which interface provides idempotency

2.1 HTTP interfaces that support idempotency

The GET, PUT and DELETE methods defined in the HTTP specification should be idempotent.

  • GET method

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.

The GET method is to query the server, it will not have side effects on the system, and it is idempotent (it does not mean that every request is the same result )

  • PUT method

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.

That is to say, the PUT method firstly judges whether there is a related record in the system, if there is a record, it updates the record, if not, it adds a new record.

  • DELETE method

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.

The DELETE method deletes the associated record on the server.

2.2 Actual business

It is now simplified to such a system, the order system and payment system for the user to purchase goods; the order system is responsible for recording the user's purchase record and the order Status (orderStatus), and the payment system is used for payment, providing

boolean  pay ( int  accountid , BigDecimal  amount )  //For payment, deduct the user's

Interface, the order system interacts with the payment system through a distributed network.

In this case, the payment system has deducted the money, but the order system has not obtained the exact result due to network reasons, so the order system needs to retry.
It can be seen from the above figure that the payment system does not achieve the idempotency of the interface. The first call and the second call of the order system, the user is deducted twice, which does not meet the idempotency principle (the same order, no matter what No matter how many times it is called, the user will only be charged once).
If you need to support idempotency, the payment interface needs to be modified to the following interface:

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是相同的,对系统同样没有产生修改。

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326986613&siteId=291194637