微服务设计笔记(9)—— REST 架构风格
发布日期:2021-06-29 21:02:00 浏览次数:2 分类:技术文章

本文共 2477 字,大约阅读时间需要 8 分钟。

REST 即表述性状态传递(英文: Representational State Transfer ,简称 REST )一种软件架构风格 。 它是一种针对网络应用的设计和开发方式,可以降低开发的复杂性,提高系统的可伸缩性 。 这里我们讨论下如何使用 REST 架构风格来解决微服务集成问题 。

REST 是 RPC 的一种替代方案 。 其中最重要的概念是资源 。比如说处于服务之内的 Customer 对象。 服务可以根据请求来创建 Customer 对象的不同表示形式(JSON 或 XML),也就是说 , 服务资源的对外显示方式和内部存储方式之间可以完全解耦 。

1 HTTP

REST 最常使用 HTTP 来实现。 因为 HTTP 设计了很多动词,来表示不同的操作,比如 GET、POST 等,它们能够很好地与服务资源结合使用,所以很容易实现 REST 。

比如一个 Customer 对象资源,我们可以只定义一个接口,然后通过 HTTP 协议的不同动词对该资源进行不同的操作 。 比如,发起一个 GET 请求来获取资源; POST 请求来创建资源。

HTTP 拥有一个大的生态系统 , 系统内包含了很多支撑工具或技术 。 比如 Varnish (HTTP 缓存代理) 、Apache mod_proxy (负载均衡器) 以及许多 HTTP 监控工具(Fiddler) 等 。 这些工具可以很好地帮助我们处理 HTTP 请求 , 并会以聪明的方式对这些请求进行路由,保障负载均衡 , 而且这些工作对终端用户来说是完全透明的 。HTTP 还提供了一系列安全控制机制供我们使用,比如基本认证或客户端证书认证等等 。

RPC 的 SOAP ( webService 简单对象访问协议)就是基于 HTTP 进行路由的,可惜的是,它只用到 HTTP 很少的特性。而 HTTP 关键特性,比如动词或错误码,都没有用到。

2 HATEOAS

REST 引入了 HATEOAS ( Hypermedia As The Engine Of Application State)概念。

介绍这个概念之前,我们先看看亚马逊网站吧。 随着时间的推移,网站将不断改版 , 购物车的位置 、 商品链接等,都有可能会发生变化 , 但我们足够灵活, 仍然能从页面上找到它们。只要满足用户和网站之间的隐式契约 , 那么网站的这些改版就不会破坏网站的基础功能 。

比如一个音乐网站,我们访问某个音乐专辑资源,会得到这些 XML 数据:

Give Blood
Awesome, short, brutish, funny and Loud. Must buy!

我们通过其中的超媒体 <link rel="/artist" href="artist/thebrakes"/> 就可以知道具体的专辑作者信息。而通过 <link rel="/instantpurchase" href="/instantpurchase/1234"/> 可以知道如何购买这张专辑。

HATEOAS 的概念就是:调用者不需要知道购买专辑的具体请求路径, 只需要能够访问到该专辑的资源 , 通过隐式约定,找到专辑的购买链接 , 然后请求这个链接即可。这样就可以在客户端和服务端之间,实现松耦合。修改了服务端,不再需要同步修改客户端代码进行适配啦。

不足之处是:

  1. 客户端和服务端之间的通信次数较多 , 因为客户端需要不断地发现链接,然后请求,接着再发现链接 , 直到找到自己想要进行的那个操作。建议一开始先让客户端去自行遍历和发现它想要的链接 , 然后在必要情况下,再进行优化。
  2. 这么做需要一定的成本投入 , 而且得到回报的时间较长。

3 JSON/XML

基于 HTTP 的 REST 能够提供多种不同的响应形式,比如 JSON 或 XML。

JSON 更加流行,因为无论从形式上还是从使用方法上来说,它都比 XML 更简单 。 可惜,它没有像 XML 那样的超媒体链接。不过,我们可以使用 HAL( HypertextApplication Language, 超文本应用语言)为其定义超文本标准格式。

我们可以通过 HTTP 发送任何格式的数据 , 比如二进制数据 。 也有直接使用 HTML,因为现在有很多现成的 HTML 解析器可用。

4 设计先行

Spring Boot 框架可以很容易地表示数据库对象 , 并把它们反序列化成进程内的对象 , 然后直接暴露给外部 。这样做,虽然项目可以很快地运转起来,但也牺牲了长远利益。

建议:先设计好外部接口 , 等到外部接口稳定后,再持久化微服务内部的数据 。在外部接口调测期间 ,我们可以先简单地将实体放到本地磁盘文件中。这样做的目的是:保证服务的接口是真正由调用者需求定义驱动出来的。虽然我们推迟了数据存储部分的集成,但避免了数据存储方式对外部接口的影响,所以是值得的。

5 不足

基于 HTTP 的 REST 开销与 Thrift 相比,开销较大 。 在高响应的业务场景下 , HTTP 的 REST 可能存在性能问题。在这样的场景下,我们可以采用构建于 TCP ( Transmission Control Protocol, 传输控制协议 ) 的 Websockets 技术。在初始的 HTTP 握手之后 , 客户端和服务端之间就可以直接通过 TCP 进行连接咯。

Thrift 是一种接口描述语言和二进制通讯协议,它被用来定义和创建跨语言的服务。

如果 Websockets 技术,还不能满足。那么可以使用底层的 UDP 协议( User Datagram Protocol, 用户数据报协议 ) 。很多 RPC 框架支持 UDP 协议,有些 RPC 框架甚至支持序列化和反序列化。对于 REST 来说,常用的还是 HTTP 协议。

转载地址:https://deniro.blog.csdn.net/article/details/101623036 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:说说如何使用 Element UI Table 的 slot-scope
下一篇:说说在 Python 中如何计算某段代码的运行时长

发表评论

最新留言

关注你微信了!
[***.104.42.241]2024年04月25日 04时25分55秒