HTTP幂等性

作者: 远o_O | 来源:发表于2017-12-22 11:08 被阅读67次

    一、前言

    • 基于HTTP协议的Web API是时下最为流行的一种分布式服务提供方式。
    • 互联网应用架构设计表现出了从传统的PHP、JSP、ASP.NET等服务器端动态网页向Restful API + JSON过渡的趋势,前后端分离越来越普遍。

    二、幂等性定义

    本文所要探讨的正是HTTP协议涉及到的一种重要性质:幂等性(Idempotence)。在HTTP/1.1规范中幂等性的定义是:

    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中具有重要地位。

    三、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/4231的语义是创建或更新ID为4231的帖子。对同一URI进行多次PUT的副作用和一次PUT是相同的;因此,PUT方法具有幂等性。

    四、总结

    • 一个幂等的操作典型如:

    把编号为5的记录的A字段设置为0这种操作不管执行多少次都是幂等的。
    一个非幂等的操作典型如:把编号为5的记录的A字段增加1这种操作显然就不是幂等的。
    要做到幂等性,从接口设计上来说不设计任何非幂等的操作即可。
    譬如说需求是:
    当用户点击赞同时,将答案的赞同数量+1。
    改为:当用户点击赞同时,确保答案赞同表中存在一条记录(插入之前检查这条记录是否已经存在,这在非幂等性的POST请求中,表现的尤为重要),用户、答案。赞同数量由答案赞同表统计出来。

    • 分布式高并发并不意味着每个request都处理的很快,也不意味着机器之间就不共享数据了。其次,你可以把你所有带有副作用的task都给一个guid,最后写进数据库之前查一下这个guid是否已经被执行过了。

    • 幂等性是数学中的一个概念,表达的是N次变换与1次变换的结果相同。

    相关文章

      网友评论

        本文标题:HTTP幂等性

        本文链接:https://www.haomeiwen.com/subject/pqjtgxtx.html