写点什么

REST 之中的幂等指的是什么?

  • 2013-05-11
  • 本文字数:1688 字

    阅读完需:约 6 分钟

REST (或者至少是 HTTP)的一个重要方面就是一些操作(动作)是幂等的。正如 Gregor Roth 在多年前所说的那样:

PUT 方法是幂等的。幂等的方法意味着请求成功执行所得到的的结果不依赖于该方法被执行的次数。

幂等也是在 SOA 设计模式中所讨论的一个问题。多年以来,围绕着 REST 以及相对于其他方式它所能带来的收益已经有了很多的讨论,在这个过程中,幂等只是一个方面,通常我们认为已经对其有所理解了,实际上并没有进行充分地研究。但是,最近在面向服务架构(Service Oriented Architecture)邮件列表中有一个帖子,针对这个看起来很直观的理念,激发了很多的讨论。初始的帖子是这样的:

目前我正在审视我们服务的幂等性并提出一个应用于企业的规定性指导,这个指导将会用于创建幂等服务的场景之中。问题在于,所有的服务都需要是幂等的吗?这现实吗?

它引用了另外的一篇 blog ,在这篇文章中,作者这样说:

当然,对于服务的提供者来说,实现幂等会比较复杂。而复杂性就会花费金钱。这可能就是幂等的服务如此稀少的原因。[…] 但是,服务只要成为幂等的,那么它就会非常简单,并且能够保证跨集成边界的数据一致性。服务 _ 应该 _ 是幂等的。这应该是架构和服务设计的原则。尤其是对于那些被很多消费者使用的服务更应如此。你不能将保持数据一致的复杂性推给你的消费者,对吧?消费者就是你的客户,你应该这样善待他们。如果你能为他们带来便利的话,你会有更多的消费者。

初始的这个帖子引起了很多的响应,包括来自 Cap Gemini 的 Steve Jones ,他这样说到:

幂等是 IT 行业中巨大的垃圾词汇之一,它的意思是“内存中的幂等”(idempotent in memory)。如果你有一个评论的服务,它具备更新的功能,从服务调用者的视角来看,服务必须要维护和管理状态。那你的含义就是它能够在内存中横向扩展。如果你更新状态的话,包括在数据库中,那么就不能保证是幂等的。幂等指的是当你使用相同的值调用相同的功能时,结果完全一致,这是它的数学定义。如果你改变过状态,那么就不是幂等的,而“数据库更新”并不会改变任何事情。

Mark Baker 曾经在 REST 这个话题上曾经有过很多回复,回应了 Steve:

就像你的评论样例所述,确实存在非幂等的状态更新,将一些数据更新为特定的值也会是幂等的更新…因为很显然如果用相同的输入执行多次的话,结果会是相同的。

Steve 在这一点上与 Mark 的观点是一致的:如果具有相同输入的一个操作没有改变任何的事情,那么它是幂等的。但是,如果这个操作改变了任意的状态,比如说它记录了这个请求的最后时间,那么它就不是幂等的。

在 IT 行业中,这个术语长久以来被人们滥用了,这一点我“感触颇深”,我曾经多次见过这样的场景,人们宣称一些事情是“幂等的”只是因为它在内存中是无状态的,尽管其消费者要达到的效果是记录性的事务。

Mark 同意 Steve 的严格定义,但是他相信这不能应用于初始请求的上下文之中,也就是:分布式系统中的幂等性:

[…] 这个词汇只对于接口有意义而不是实现。所以,如果我定义一个操作,比如说“set”,并将其定义为幂等的,那么它会只关系到客户端,即便在这个接口的实现中会产生日志。

另外一个参与者 Ashaf Galal,断言所有“读的服务”(reading services)都是幂等的,因为这样的服务只会返回数据。但是,Steve 指出,这是一个过于简单的视角,有时候一个操作呈现出来的是幂等的,它的实现可以做任何事情但它需要是幂等的就可以(这再次提出了这个问题,那就是这种区分是否重要):

[…] 读的功能不一定是幂等的。“getNextIterator()”是一个读的功能,它不是幂等的,因为它会渐进迭代器。银行账号请求余额可能也不是幂等的,因为会创建审计日志。两个连续调用返回的结果可能是相同的(如果没有变化发生的话),但是日志条目是不同的。

Ashaf 回应了 Steve,他说幂等是服务的属性而不是接口的属性。

客户端需要从服务那里得到适当的响应,他并不关心服务是不是幂等的,是不是要记录日志。

那么,其他人怎么想的呢?对于幂等的含义,是否还有误解?如果一个被视为幂等的操作实际上会改变一些状态,如 Steve 所提到的更新日志,那么这有关系吗?

英文原文链接: What Is Idempotent in REST?

2013-05-11 07:4526485

评论

发布
暂无评论
发现更多内容

Java中的几种阻塞队列,kalilinux渗透教程

Java 程序员 后端

Java中高级核心知识全面解析——消息队列,mybatis映射原理

Java 程序员 后端

Java基础03 Java的运算符,阿里巴巴java性能调优

Java 程序员 后端

java学习-数据类型和运算符,Java爬虫爬取视频

Java 程序员 后端

Java中的容器,Java开发进大厂面试必备技能

Java 程序员 后端

Java中高级核心知识全面解析——消息队列(1),看完这一篇就够了

Java 程序员 后端

Java反射,mysql开发教程

Java 程序员 后端

java反射map转实体类 实体转map,微服务架构的优缺点

Java 程序员 后端

Java垃圾回收机制小结以及优化建议,kafka的工作原理图

Java 程序员 后端

Java中的几种阻塞队列(1),mybatis返回主键原理

Java 程序员 后端

Java使用JDBC开发 之 DBCP连接池,保洁阿姨看完都会了

Java 程序员 后端

Java基于TCP的网络编程,在阿里工作5年了

Java 程序员 后端

Java基础复习(DayEleven),应届生面试java开发工程师的题

Java 程序员 后端

Java实现人脸检测,oppojava后端面试几面

Java 程序员 后端

Java反射(1),java架构师薪资

Java 程序员 后端

Java发送邮件,字节跳动上千道精选面试题还不刷起来

Java 程序员 后端

Java实现AES加密算法,2021最新百度、头条等公司Java面试题目

Java 程序员 后端

Java实现单链表、栈、队列三种数据结构,linux内核编程入门篇

Java 程序员 后端

Java中的Type类型详解,javase菜鸟教程

Java 程序员 后端

Java中的初始化与清理,kafka参数调优

Java 程序员 后端

模块三:如何保证设计出合理的架构? -- 学习总结

小鹿

Java如何在运行时识别类型信息?,java发展史百度百科

Java 程序员 后端

Java中高级核心知识全面解析——Dubbo,kafka入门到精通文档

Java 程序员 后端

Java在2018年的形势,MySQL优化原理分析及优化方案总结

Java 程序员 后端

Java多线程笔记,java自学视频免费

Java 程序员 后端

Java学习路线图(如何快速学Java),java数据结构与算法面试题

Java 程序员 后端

Java中的程序控制流程,java面试常问知识

Java 程序员 后端

java响应重定向发送post请求,spring+mybatis基础知识

Java 程序员 后端

Java基础知识总结(绝对经典),java项目实战视频旅行社管理系统

Java 程序员 后端

Java多态实现原理,招银网络科技java面试

Java 程序员 后端

Java大牛带你4小时开发一个SpringBoot+vue前后端分离博客项目

Java 程序员 后端

REST之中的幂等指的是什么?_SOA_Mark Little_InfoQ精选文章