首页 » 网站推广 » php幂等性技巧_深入理解Web API幂等性

php幂等性技巧_深入理解Web API幂等性

访客 2024-10-27 0

扫一扫用手机浏览

文章目录 [+]

基于HTTP协议的Web API是时下最为盛行的一种分布式做事供应办法。
无论是在大型互联网运用还是企业级架构中,我们都见到了越来越多的SOA或RESTful的Web API。
为什么Web API如此盛行呢?我认为很大程度上应归功于大略有效的HTTP协议。
HTTP协议是一种分布式的面向资源的网络运用层协议,无论是做事器端供应Web做事,还是客户端消费Web做事都非常大略。

再加上浏览器、Javascript、AJAX、JSON以及HTML5等技能和工具的发展,互联网运用架构设计表现出了从传统的PHP、JSP、ASP.NET等做事器端动态网页向Web API + RIA(富互联网运用)过渡的趋势。
Web API专注于供应业务做事,RIA专注于用户界面和交互设计,从此两个领域的分工更加明晰。
在这种趋势下,Web API设计将成为做事器端程序员的必修课。
然而,正如大略的Java措辞并不虞味着高质量的Java程序,大略的HTTP协议也不虞味着高质量的Web API。
要想设计出高质量的Web API,还须要深入理解分布式系统及HTTP协议的特性。

php幂等性技巧_深入理解Web API幂等性

幂等性定义

本文所要磋商的正是HTTP协议涉及到的一种主要性子:幂等性(Idempotence)。
在HTTP/1.1规范中幂等性的定义是:

php幂等性技巧_深入理解Web API幂等性
(图片来自网络侵删)

Methods can also have the property of "idempotence" in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request.

从定义上看,HTTP方法的幂等性是指一次和多次要求某一个资源该当具有同样的副浸染。
幂等性属于语义范畴,正如编译器只能帮助检讨语法缺点一样,HTTP规范也没有办法通过格式等语法手段来定义它,这可能是它不太受到重视的缘故原由之一。
但实际上,幂等性是分布式系统设计中十分主要的观点,而HTTP的分布式实质也决定了它在HTTP中具有主要地位。

分布式事务 vs 幂等设计

为什么须要幂等性呢?我们先从一个例子提及,假设有一个从账户取钱的远程API(可以是HTTP的,也可以不是),我们暂时用类函数的办法记为:

bool withdraw(account_id, amount)

withdraw的语义是从account_id对应的账户中扣除amount数额的钱;如果扣除成功则返回true,账户余额减少amount;如果扣除失落败则返回false,账户余额不变。
值得把稳的是:和本地环境比较,我们不能轻易假设分布式环境的可靠性。
一种范例的情形是withdraw要求已经被做事器端正确处理,但做事器真个返回结果由于网络等缘故原由被掉丢了,导致客户端无法得知处理结果。
如果是在网页上,一些不恰当的设计可能会利用户认为上一次操作失落败了,然后刷新页面,这就导致了withdraw被调用两次,账户也被多扣了一次钱。
如图1所示:

这个问题的办理方案一是采取分布式事务,通过引入支持分布式事务的中间件来担保withdraw功能的事务性。
分布式事务的优点是对付调用者很大略,繁芜性都交给了中间件来管理。
缺陷则是一方面架构太重量级,随意马虎被绑在特定的中间件上,不利于异构系统的集成;另一方面分布式事务虽然能担保事务的ACID性子,而但却无法供应性能和可用性的担保。

另一种更轻量级的办理方案是幂等设计。
我们可以通过一些技巧把withdraw变成幂等的,比如:

int create_ticket() bool idempotent_withdraw(ticket_id, account_id, amount)

create_ticket的语义是获取一个做事器端天生的唯一的处理号ticket_id,它将用于标识后续的操作。
idempotent_withdraw和withdraw的差异在于关联了一个ticket_id,一个ticket_id表示的操作至多只会被处理一次,每次调用都将返回第一次调用时的处理结果。
这样,idempotent_withdraw就符合幂等性了,客户端就可以放心地多次调用。

基于幂等性的办理方案中一个完全的取钱流程被分解成了两个步骤:1.调用create_ticket()获取ticket_id;2.调用idempotent_withdraw(ticket_id, account_id, amount)。
虽然create_ticket不是幂等的,但在这种设计下,它对系统状态的影响可以忽略,加上idempotent_withdraw是幂等的,以是任何一步由于网络等缘故原由失落败或超时,客户端都可以重试,直到得到结果。
如图2所示:

和分布式事务比较,幂等设计的上风在于它的轻量级,随意马虎适应异构环境,以及性能和可用性方面。
在某些性能哀求比较高的运用,幂等设计每每是唯一的选择。

HTTP的幂等性

HTTP协议本身是一种面向资源的运用层协议,但对HTTP协议的利用实际上存在着两种不同的办法:一种是RESTful的,它把HTTP当成运用层协议,比较虔诚地遵守了HTTP协议的各种规定;另一种是SOA的,它并没有完备把HTTP当成运用层协议,而是把HTTP协议作为了传输层协议,然后在HTTP之上建立了自己的运用层协议。
本文所谈论的HTTP幂等性紧张针对RESTful风格的,不过正如上一节所看到的那样,幂等性并不属于特定的协议,它是分布式系统的一种特性;以是,不论是SOA还是RESTful的Web API设计都该当考虑幂等性。

下面将先容HTTP GET、DELETE、PUT、POST四种紧张方法的语义和幂等性。

HTTP GET方法用于获取资源,不应有副浸染,所以是幂等的。

比如:

GET http://www.bank.com/account/123456

不会改变资源的状态,不论调用一次还是N次都没有副浸染。
请把稳,这里强调的是一次和N次具有相同的副浸染,而不是每次GET的结果相同。

GET http://www.news.com/latest-news

这个HTTP要求可能会每次得到不同的结果,但它本身并没有产生任何副浸染,因而是知足幂等性的。

HTTP DELETE方法用于删除资源,有副浸染,但它该当知足幂等性。
比如:

DELETE http://www.forum.com/article/4231

,调用一次和N次对系统产生的副浸染是相同的,即删掉id为4231的帖子;因此,调用者可以多次调用或刷新页面而不必担心引起缺点。

比较随意马虎稠浊的是HTTP POST和PUT。
POST和PUT的差异随意马虎被大略地误认为“POST表示创建资源,PUT表示更新资源”;而实际上,二者均可用于创建资源,更为实质的差别是在幂等性方面。
在HTTP规范中对POST和PUT是这样定义的:

The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line ...... If a resource has been created on the origin server, the response SHOULD be 201 (Created) and contain an entity which describes the status of the request and refers to the new resource, and a Location header.The PUT method requests that the enclosed entity be stored under the supplied Request-URI. If the Request-URI refers to an already existing resource, the enclosed entity SHOULD be considered as a modified version of the one residing on the origin server. If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new resource by the requesting user agent, the origin server can create the resource with that URI.

POST所对应的URI并非创建的资源本身,而是资源的吸收者。
比如:

POST http://www.forum.com/articles

的语义是在

http://www.forum.com/articles

下创建一篇帖子,HTTP相应中应包含帖子的创建状态以及帖子的URI。
两次相同的POST要求会在做事器端创建两份资源,它们具有不同的URI;以是,POST方法不具备幂等性。
而PUT所对应的URI是要创建或更新的资源本身。
比如:

PUT http://www.forum/articles/423

1的语义是创建或更新ID为4231的帖子。
对同一URI进行多次PUT的副浸染和一次PUT是相同的;因此,PUT方法具有幂等性。

在先容了几种操作的语义和幂等性之后,我们来看看如何通过Web API的形式实现前面所提到的取款功能。
很大略,用POST /tickets来实现create_ticket;用

PUT /accounts/account_id/ticket_id?amount=xxx

来实现idempotent_withdraw。
值得把稳的是严格来讲amount参数不应该作为URI的一部分,真正的URI该当是

/accounts/account_id/ticket_id

,而amount该当放在要求的body中。
这种模式可以运用于很多场合,比如:论坛网站中防止意外的重复发帖。

总结

上面大略先容了幂等性的观点,用幂等设计取代分布式事务的方法,以及HTTP紧张方法的语义和幂等性特色。
实在,如果要追根溯源,幂等性是数学中的一个观点,表达的是N次变换与1次变换的结果相同,有兴趣的读者可以从Wikipedia上进一步理解。

来源 cnblogs | Todd Wei

原标题: 《理解HTTP幂等性》

如有侵权请联系删除

标签:

相关文章

Python编程从入门到精通,探索编程之美

编程已经成为现代社会的一项基本技能。Python作为一种简单易学、功能强大的编程语言,在我国教育领域备受关注。本文将从Python...

网站推广 2025-03-02 阅读1 评论0

Scum07代码编程之美与适用方法

编程已成为当今社会不可或缺的技能之一。Scum07代码作为一款经典的编程语言,在我国众多程序员中备受推崇。本文将深入解析Scum0...

网站推广 2025-03-02 阅读1 评论0

Linux环境下的前端代码运行优化与步骤

前端技术逐渐成为软件开发的核心。Linux操作系统因其稳定性、安全性、开放性等特点,成为众多开发者和企业青睐的运行环境。本文将从L...

网站推广 2025-03-02 阅读1 评论0