RESTful 架构

一、 起源

REST这个词是Roy Thomas Fielding在他2000年的博士论文中提出的。

Fielding是一个非常重要的人,他是HTTP协议(1.0版和1.1版)的主要设计者、Apache服务器软件的作者之一、Apache基金会的第一任主席。

This dissertation explores a junction on the frontiers of two research disciplines in computer science: software and networking.
Software research has long been concerned with the categorization of software designs and the development of design methodologies, but has rarely been able to objectively evaluate the impact of various design choices on system behavior.
Networking research, in contrast, is focused on the details of generic communication behavior between systems and improving the performance of particular communication techniques, often ignoring the fact that changing the interaction style of an application can have more impact on performance than the communication protocols used for that interaction.
My work is motivated by the desire to understand and evaluate the architectural design of network-based application software through principled use of architectural constraints, thereby obtaining the functional, performance, and social properties desired of an architecture.
When given a name, a coordinated set of architectural constraints becomes an architectural style.
"本文研究计算机科学两大前沿--软件和网络--的交叉点。
长期以来,软件研究主要关注软件设计的分类、设计方法的演化,很少客观地评估不同的设计选择对系统行为的影响。
而相反地,网络研究主要关注系统之间通信行为的细节、如何改进特定通信机制的表现,常常忽视了一个事实,那就是改变应用程序的互动风格比改变互动协议,对整体表现有更大的影响。
我这篇文章的写作目的,就是想在符合架构原理的前提下,理解和评估以网络为基础的应用软件的架构设计,得到一个功能强、性能好、适宜通信的架构。"

如何评估web架构?

论文的目的之一是为选择或创建应用程序的架构时提供设计指导,为此需要一个评估机制,架构设计很难客观的进行评估和比较,像艺术品一样,架构通常为完整的作品呈现。但我们可以通过一组协调的架构约束(SOAP或REST)看做一种样式的应用。当他们的约束不冲突时,可以将样式组合起来形成混合样式。我们在这些样式中总结出属性,然后根据属性的权重值来进行评估。但不是权重值高或低就一定好或坏,应当在各个属性中取得可接受的均衡。

评估web架构的关键属性:

  1. 性能 Performance:影响高可用的关键因素

    1. 网络性能 Network Performance. 用于描述通信的某些属性

      1. Throughput 吞吐量:小于等于带宽 bandwidth

      2. Overhead 开销:首次开销,每次开销

        样式通过影响每个用户操作的交互次数和数据元素的粒度来影响网络性能

    2. 用户感知的性能 User-perceived Performance

      1. Latency 延迟:发起请求到接收到响应的时间

      2. Completion 完成时间:完成一个应用动作所花费的时间

        常见的提高用户感知性能的做法如:逐步加载页面,大文件压缩等

    3. 网络效率 Network Efficiency

      1. 重用缓存、减少交互次数、传输距离更近CDN等
  2. 可伸缩性 Scalability:支持部署可以互相交互的大量组件

  3. 简单性 Simplicity:易理解、易实现、易验证

  4. 可修改性 Modifiability:对系统作出修改的难易程度,由可进化性、可定制性、可扩展性、可配置性、可重用性构成

    1. 可进化性 Evolvability:一个组件独立升级而不影响其他组件
    2. 可扩展性 Extensibility :向系统添加功能,而不会影响到系统的其他部分
    3. 可定制性 Customizability :临时性、定制性地更改某一要素来提供服务, 不对常规客户产生影响
    4. 可配置性 Configurability :应用部署后可通过修改配置提供新的功能
    5. 可重用性 Reusabilit :组件可以不做修改在其他应用在使用
  5. 可见性 Visiable:对两个组件间的交互进行监视或者仲裁的能力。如缓存、分层设计等

  6. 可移植性 Portability:在不同的环境下运行的能力

  7. 可靠性 Reliability:出现部分故障时,对整体影响的程度

可视化图表:-为负面影响,+为正面影响,±表示取决于问题域的某些方面

数据流风格 Data-flow Styles

优点:简单性、可进化性、可扩展性、可配置性、可重用性

管道和过滤器 pipe-line filter(PF)

例如:apache cocoon

PF支持重用:只要两个过滤器就它们之间正在传输的数据达成一致(可重用性)

PF系统可以轻松维护和增强:可以将新过滤器添加到现有系统中(可扩展性)

支持并发执行(用户感知的性能)

统一管道和过滤器 Uniform Pipe filter(UPF)

特点是:所有过滤器必须具有相同接口的约束

这样做提高了可见性和简单性和可移植性,但因为需要将数据转换为指定的格式,则可能降低网络性能。

复制风格 Replication Styles

优点:用户可察觉的性能、可伸缩性,网络效率、可靠性也可以得到提升

复制存储库 Replicated Repository(RR)

例如:CVS,mysql

通过让多个进程提供相同的服务(可使用nginx反向代理)来提高数据的可访问性和服务的可伸缩性.

可伸缩性和可靠性更好,保持一致性是主要问题。

缓存($)

网络效率更高,可伸缩性和可靠性更好。

分层风格 Hierarchical

优点:简单性、可进化性、可伸缩性、可重用性

客户端-服务器 client-service(CS)

可伸缩性 连接器所使用的机制经常引用,例如RPC或者MQ。

分层系统 Layered System(LS)和分层客户端服务器 Layered Client-Server(LCS)

分层系统是按层次结构组织的,每一层都为其上一层提供服务,并使用其下一层的服务,从而减少了跨多层的耦合,提高了可扩展性和可重用性。

客户端无状态服务器 Client-Stateless-Server(CSS)

基于CS,其附加约束是服务器组件上不允许有会话状态。

从客户端到服务器的每个请求都必须包含理解该请求所需的所有信息,
并且不能利用服务器上存储的任何上下文。
会话状态完全保留在客户端上。

提升了可见性、可伸缩性、可靠性,但重复数据导致降低网络性能.

这些限制改善了可见性,可靠性和可伸缩性的属性。
可见性得到了改善,因为监视系统不必为了确定请求的全部性质而超出单个请求数据。
可靠性得到改善,因为它简化了从部分故障中恢复的任务,可伸缩性得到了改善,因为不必在请求之间存储状态,这使得服务器组件可以快速释放资源并进一步简化实现。
它可能会通过增加在一系列请求中发送的重复数据(每次交互开销)来降低网络性能.
因为该数据无法在共享上下文中留在服务器上。

3.4.4客户端缓存无状态服务器(C $ SS)

提升性能

缓存充当客户端和服务器之间的中介,在其中,对先前请求的响应(如果被认为是可缓存的)可以被重用,
添加缓存组件的优势在于它们有潜力部分或完全消除某些交互,从而提高效率和用户感知的性能。

分层客户端缓存无状态服务器(LC $ SS)

在C $ SS的基础上添加代理或网关。

变体CS分层风格

远程回话 Remote Session, RS

- CS 变体,服务器保存Application state 应用状态(比如FTP,需要知道上次用户访问所在的目录)
- 可伸缩性、可见性差

远程数据访问 Remote Data Access,RDA

- CS变体,Application state应用状态同时分布在客户端和服务器
- 巨大的数据及有可能通过迭代而减少
- 简单性、可伸缩性差

移动代码样式 Mobile Code Styles

优点:网络性能,网络效率,可靠性,扩展性,可配置性

虚拟机 Virtual Machine, VM

  • 分离指令与实现

远程求值 Remote Evaluation, REV

  • 基于 CS 的 VM,将代码发送至服务器执行

- 按需代码 Code on Demand, COD

  • 服务器在响应中发回处理代码,在客户端执行

  • 优秀的可扩展性和可配置性,提升用户可察觉性能和网络效率

分层、按需代码、缓存、无状态、客户端服务器

  • Layered-Code-on-Demand-Client-Cache-Stateless-Server, LCODC$SS

  • LC$SS+COD

移动代理 Mobile Agent, MA

  • 相当于 REV+COD

点对点风格 Peer-to-Peer Styles

优点:可进化型,可扩展性,可配置型,可重用性

Event-based Integration ,EBI:

  • 基于事件集成系统,如由类似 Kafka 这样的消息系统 + 分发订阅来消除耦合
  • 优秀的可重用性、可扩展性、可进化性
  • 缺乏可理解性
  • 由于消息广播等因素造成的消息风暴,可伸缩性差

Chiron-2,C2

参见论文《A Component- and Message-Based Architectural Style for GUI Software》 • 相当于 EBI+LCS,控制了消息的方向

Distributed Objects ,DO

  • 组件结对交互

Brokered Distributed Objects ,BDO

  • 引入名字解析组件来简化 DO,例如 CORBA

风格演化

原点 通过添加分离约束 形成 CS样式 获得了 (可移植性、可伸缩性),分离允许组件独立发展

形成CS之后,允许服务端集群化 也就形成了RR

继续添加无状态约束 形成CSS样式 获得了(可见性、可靠性、可伸缩性),但降低了网络性能,因为会发送重复数据。

以便从客户端到客户端的每个请求服务器必须包含理解请求所必需的所有信息,并且不能利用服务器上存储的任何上下文。
因此,会话状态完全保留在客户端上。

继续添加缓存约束 形成了 C$SS样式 获得了(可伸缩性、用户感知的性能)

继续添加统一接口约束

继续添加分层的约束 形成了LC$SS样式 加强了(可伸缩性、简单性、可进化型、可移植性)

增加了数据处理的开销和延迟,从而降低了用户感知的性能,分层系统和统一的界面约束的组合产生了类似于统一的管道和过滤器样式的架构属性

继续添加按需编码约束 形成了LCODC$SS.

REST允许通过以applet或脚本的形式下载并执行代码来扩展客户端功能。
通过减少预先实现的功能数量,简化了客户端。
部署后允许下载功能可以提高系统的可扩展性。
但是,它也降低了可见性,因此仅是REST中的可选约束。

继续添加统一接口的约束 形成了REST样式 提高了(可见性),统一的接口会降低效率,因为信息是以标准化形式而不是特定于应用程序需求的形式进行传输的。

REST (简单性、网络效率、可伸缩性、可见性、可靠性、可移植性、可以执行、可扩展性、可配置型、用户可察觉的性能、可重用性)

整体上应用时会强调组件交互的可伸缩性,接口的通用性,组件的独立部署以及中间组件,以减少交互延迟,增强安全性并封装旧系统

REST提供了一组体系结构约束,这些约束在整体上应用时会强调组件交互的可伸缩性,接口的通用性,组件的独立部署以及中间组件,以减少交互延迟,增强安全性并封装旧系统。

RESTful主要元素

代表性状态转移(REST)样式是分布式超媒体系统中体系结构元素的抽象。REST忽略了组件实现和协议语法的细节.

涵盖了对组件,连接器和数据的基本约束,这些约束定义了Web体系结构的基础.

  1. 数据元素

    将信息从存储位置移动到人类阅读器将使用的位置.一般有三个基本选项:

    ​ 1)在数据所在的位置渲染数据并将固定格式的图像发送给接收者;(客户端-服务器样式)

    ​ 封装良好,限制严格,可伸缩性差

    ​ 2)用渲染引擎封装数据,然后将两者发送给接收者;(移动对象样式)

    ​ 统一引擎处理,限制范围,性能较差。

    ​ 3)将原始数据与描述数据类型的元数据一起发送给接收者,以便接收者可以选择自己的呈现引擎。

    ​ 简单,可伸缩,性能良好,信息无法隐藏,要求发送方和接收方达成共识。

    REST为以上三个选项的混合,通过对元数据的数据类型的共享理解,将所显示的内容的范围限制为标准化接口.通过一组标准数据类型及其匹配的传输格式进行通信,这些数据类型是根据接受者的能力或需求以及资源的性质动态选择的。rest可以将客户端-服务器样式的关注点分离,从而避免服务器可伸缩性的问题,允许通过通用接口隐藏信息已实现服务的封装和演进。

    数据元素 现代网络示例
    资源 超文本引用的预期概念目标
    资源标识符 URL,URN
    表示 HTML文件,JPEG图像
    表示元数据 媒体类型,最后修改时间
    资源元数据 源链接,替代,变化
    控制数据 if-modified-since,缓存控制
  2. 资源

    1. REST中信息的关键抽象是一种资源,资源是到一组实体的概念映射,可以命名的任何信息都可以是资源.
    2. 与面向对象设计类似,资源是以名词为核心来组织的,首先关注的是名词。
    3. 一个资源可以由一个或多个URI来标识。URI既是资源的名称,也是资源在Web上的地址。
  3. 表示

    1. 表示是一段对于资源在某个特定时刻的状态的描述。
    2. "资源"是一种信息实体,它可以有多种外在表现形式.
    3. 在HTTP请求的头信息中一般用Accept和Content-Type字段指定。
  4. 状态转换

    1. 在客户端和服务器端之间转移(transfer)代表资源状态的表述。
    2. 是客户端和服务器的一个互动过程,这种转换是建立在表现层之上的。
    3. 通过统一接口来实现状态转换。

RESTful的四个级别

由马丁·福乐(Martin Fowler)在一片文章中提出:https://martinfowler.com/articles/richardsonMaturityModel.html

第0级 (Remote Procedure Invocation)

  • 使用HTTP作为远程交互的传输系统,但不使用任何Web机制.

  • 全部使用POST请求,参数放在HTTP协议的body里面。

  • 使用时像是传统的RPC,比如:基于SOAP的WS。

  • 问题是客户端需要明确知道所有的服务、子服务、入参、出参的各种含义。

第1级 (Resource)

  • 每个URI即代表一个资源
  • 不需要面向整个服务对话,而是面向单个资源对话
  • 依照资源的方式访问到服务且可寻址。
  • 一般用名词表示资源,且以复数形式出现在URI中。
  • 以 “/” 结尾表示一组资源;以"/{**ID}"标识单独资源

第2级 (Http verb)

  • HTTP定义了多种method,被用于表述该请求是哪一类动作。在URI中将不能出现动词,只能有名词。

    • GET:主要的获取信息方法,大量的性能优化都针对该方法,幂等方法
    • HEAD:类似 GET 方法,但服务器不发送 BODY,用以获取 HEAD 元数据,幂等方法
    • POST:常用于提交 HTML FORM 表单、新增资源等
    • PUT:更新资源,带条件时是幂等方法
    • DELETE:删除资源,幂等方法
    • CONNECT:建立 tunnel 隧道
    • OPTIONS:显示服务器对访问资源支持的方法,幂等方法
    • TRACE:回显服务器收到的请求,用于定位问题。有安全风险
    • PATCH:是对 PUT 方法的补充,用来对已知资源进行局部更新
    • 其他的WebDAV不再赘述,感兴趣的课自行搜索
  • HTTP 定义了多种status,用户表述相应的状态。针对不同的动作也有不同的状态含义。
    1** 服务器收到请求,需要请求者继续执行操作,HTTP1.0 不支持.

    2** 成功处理请求

    3** 重定向使用 Location 指向的资源或者缓存中的资源。(次数不应超过 5 次,以防止死循环)

    4** 客户端出现错误

    5** 服务器端出现错误

    详见 : https://www.runoob.com/http/http-status-codes.html

    特别说明:

    我们很多请求都使用了200来返回成功执行的请求,但其实2**中有很多带有具体语义的状态码.如:

    创建时不返回200,而返回 201 Created。 表示新资源被创建成功。用于在post请求时被返回。

    删除时不返回200,而返回 204 No Content。表示没有进一步需要删除的资源了。200在delete请求时表示该资源被成功删除了,但您有需要删除的相关资源。其语义是不携带响应包体,一般用于暗示客户端无需更新当前页面的视图。

    在接收异步请求时使用202 Accepted。表示已经接受请求,但未处理完成。客户端会在间隔一段时间(若服务端指定,可以随状态一同返回)后循环调用。

    4** 也很值得说明一下。服务器接收请求后处理不了,并认为是由于客户端的错误导致的无法处理就会使用4**。

    请求参数验证失败时会返回400 Bad Request ,认证失败时 会返回401 Unauthorized.409 Conflict 一般在put请求时会用到,表示自愿已存在。

第3级 (Hypermedia Controls)

  • 中文翻译“超文本驱动”或“将超媒体作为应用状态的引擎”(Hypermedia As The Engine Of Application State,来自Fielding博士论文中的一句话,缩写为HATEOAS)
  • 资源之间通过超链接相互关联,超链接既代表资源之间的关系,也代表可执行的状态迁移.
  • 通过超媒体暴露出服务器所提供的资源,服务器提供了哪些资源是在运行时通过解析超媒体发现的,而不是事先定义的。

关于不同层级的总结:

  • 级别1通过使用分而治之解决了处理复杂性的问题,将大型服务端点分解为多个资源。
  • 级别2引入了一组标准动词,以便我们以相同的方式处理类似的情况,从而消除了不必要的变体。
  • 级别3引入了可发现性,从而提供了使协议更具自记录性的方法。

参考文章:

https://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm

https://martinfowler.com/articles/richardsonMaturityModel.html

http://www.ruanyifeng.com/blog/2011/09/restful.html

https://www.cnblogs.com/klb561/p/9286283.html

RESTful架构和实现级别相关推荐

  1. RESTful 架构基础

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 来自:唐尤华 译自:https://dzone.com/refca ...

  2. 到底什么是RestFul架构?

    场景描述:REST(Representational State Transfer)架构风格是一种世界观,把信息提升为架构中的一等公民.通过 REST 可以实现系统的高性能.可伸缩.通用性.简单性.可 ...

  3. 什么才是真正的 RESTful 架构?

    笔记: 一个资源有且仅可对应一个实际物理上的存储项,一个存储项可以对应多个资源.对于某个存储项的多步骤操作,可以尝试用多个资源分别表示,而不是用批操作? 对于第三级,学习使用返回"key:链 ...

  4. 什么才是真正的 RESTful 架构

    What? Wikipedia: 表征性状态传输(英文:Representational State Transfer,简称REST)是Roy Fielding博士于2000年在他的博士论文中提出来的 ...

  5. [转] 理解RESTful架构

    FROM:http://www.ruanyifeng.com/blog/2011/09/restful.html 越来越多的人开始意识到,网站即软件,而且是一种新型的软件. 这种"互联网软件 ...

  6. 理解RESTful架构

    越来越多的人开始意识到,网站即软件,而且是一种新型的软件. 这种"互联网软件"采用客户端/服务器模式,建立在分布式体系上,通过互联网通信,具有高延时(high latency).高 ...

  7. 初识Restful架构

    1.对Rest(Restful)的理解 理解RESTful架构 怎样用通俗的语言解释REST,以及RESTful 维基百科:Representational state transfer 2.Rest ...

  8. [转载] 理解RESTful架构

    原文: http://www.ruanyifeng.com/blog/2011/09/restful.html 理解RESTful架构 作者: 阮一峰 日期: 2011年9月12日 越来越多的人开始意 ...

  9. RESTful架构风格

    REST即Representational State Transfer的缩写,可译为"表现层状态转化".REST最大的几个特点为:资源.统一接口.URI和无状态. 资源 所谓&q ...

最新文章

  1. EXC_BAD_ACCESS错误
  2. Oracle8i 到Oracle 12c的2014年最新PSU、Bundle Patch、SPU信息
  3. SectionIndexer中的getSectionForPosition()与getPositionForSection()
  4. 为什么会有这么多python?其实python并不是编程语言!
  5. Windows 2008 R2服务管理器刷新失败
  6. JUnit 5 –参数化测试
  7. Fortinet SD-Branch保障医疗服务机构安全组网
  8. php如何监听页面滚动,html5中在元素滚动条在滚动时触发的事件onscroll
  9. html 表单控制器,c# – html表单发布到mvc控制器
  10. JVM优化系列-详解常用的虚拟机调优参数
  11. 安卓案例:利用内容提供者显示和添加联系人
  12. python沙箱逃逸小结
  13. 一张图看懂OSPF邻接关系建立及报文类型
  14. 微信小程序熊猫抽奖盒子panda_luckybox3.3.1多开版
  15. 探究Stereo中的DSI(Disparity Space Image)到底是指什么
  16. android图片模糊效果,Android下实现高效的模糊效果
  17. 磨金石教育摄影技能干货分享|什么是序列摄影?它让摄影更加深刻
  18. C++switch语句详解
  19. GPU价格暴跌,腾讯押注元宇宙,苹果在华招聘汽车人,今日更多大新闻在此
  20. 成功解决windows10连上了wifi但是没网的问题

热门文章

  1. 常用MAVROS话题和服务
  2. 语雀三个月会员,兑换码领取
  3. iPhone删掉的照片能恢复吗?iPhone最近删除的照片怎么恢复?
  4. 企业如何使用OA系统?OA系统有哪些功能和应用的场景?
  5. 静态网页的广告banner部分
  6. 计算机相关专业零基础论文画图详细教程(避免掉坑教程)
  7. XXXXXXXXXXX
  8. Windows平台录音类封装:AudioRecordWindows
  9. Java---设计【超市商品管理系统】
  10. 微信小程序rich-text图片不显示及图片过大问题解决办法