流行的客户端-服务器架构将通信分为两部分:一部分承担所有繁重任务并提供服务,称为服务器;另一部分享受这些服务,称为客户端。
在一般的客户端-服务器通信中,客户端简单地向服务器发送请求,请求资源或服务,服务器则响应这一请求。
对于客户端-服务器通信,客户端和服务器需要拥有能够理解它们所交流的协议的库。协议是互联网通信的语言或规则集。它们是遵循特定指南在互联网上传输数据的传输机制。
客户端通信的第二个重要方面是消息格式,客户端和服务器双方都必须同意此格式。消息格式基于某些模式,如果不遵循这些模式,通信将无法进行。消息格式可以类似于遵循模式的XML,或者是必须包含特定键值对的JSON文件。
理解这种通信方式的另一个重要方面是,它基于请求和响应机制,这意味着服务器只在客户端发起通信时才进行交流。使用REST和GraphQL时,这种通信主要是单向的。这是一个基本问题,将由gRPC等技术解决。
为什么会出现REST?
在90年代初期,一种流行的客户端-服务器协议SOAP使用XML消息格式,其模式是硬编码的,非常僵化。正是这种缺乏灵活性导致了SOAP的废弃和REST的兴起。
随着JavaScript的日益流行,JSON文件格式的普及也随之增长。JSON简单易懂,使用方便,其消息格式仅包含一些键值对。
简而言之,REST是一种通过HTTP协议(传输机制)在互联网上传输JSON消息的规范。使用REST,无需担心创建模式。
什么是REST?
我们讨论了REST的出现。现在让我们深入了解其核心技术。REST代表表述性状态转移,是一种标准化的软件架构风格,广泛应用于工业界的API。
REST流行和广泛使用的原因
- REST为通信架构提供了简单且标准化的方式。在使用REST时,无需担心消息或数据的格式化。每次发送消息时,都不必操心格式问题,因为它都是标准化的,且被业界广泛采用。
- REST具有可扩展性。如果服务规模扩大,需要更多功能,可以轻松重构服务器,而不必担心REST对服务器性能的影响,并且可以在完全隔离的情况下创建新功能,除非它们干扰了数据。
- REST是无状态的。这意味着每个请求都将包含服务器必须理解的数据。服务器的架构使得服务器能够回忆起该请求的信息,但在REST架构中,会话状态存储在客户端,这使得服务器更高效,并且为服务器提供了较少的工作量以实现更精细的功能。
- 最后但同样重要的是,REST是一种高性能架构,并支持缓存。
何时使用REST
设想你正在为一个餐厅制作网站。你将所有菜单在线,并将食品项目分为三个类别:
- 开胃菜
- 主菜
- 饮料
现在,假设你想在线查看所有饮料。在REST架构中,你可以轻松且一致地将所有资源分区到API端点上。当然,你可以使用多种认证方式来确保它们的安全。
在这种情况下,我们向服务器发送GET请求到一个端点,我们可以从中获取饮料资源数据。
同样,我们可以在REST API中执行所有CRUD(创建、读取、更新、删除)操作,这使其适合不需要大量数据传输且不需要实时性的大型项目。
REST在数据高效传输是重要因素的项目中表现最佳。缓存是REST的另一个特性,对于标准应用程序如食品预订应用、酒店预订应用、博客网站、在线论坛网站等非常有用。
REST的局限性和问题
REST虽然优秀,但在某些情况下其缺点也相当关键。让我们来探讨这些问题。
- 首先是双向通信的需求。
如果服务器需要向客户端发送数据怎么办?服务器想要主动发起通信。在REST架构中,这是不可能的。当然,你可以使用一些技巧,但它们并不实用。 - 设想构建一个实时比分网站。如何让服务器向客户端发送请求以更新比分数据呢?我们可以让客户端每10秒发送一次请求,但这绝非良策。这会加重服务器负担,可能导致速度问题。
- REST架构纯粹基于请求和响应,并不支持数据流(连续事件处理)。
- REST的无状态特性既是福音也是诅咒,因为在REST架构中你无法决定数据的状态。
gRPC为何应运而生?
为了解决REST的第一个问题,即双向通信的需求,WebSocket被发明出来,它允许服务器发起通信,但问题在于它没有格式。它只是发送字节,没有任何限制。
WebSocket本身并无问题,真正的问题在于任何类型的通信都需要一个协议,而每个协议都需要一个客户端库,以便使用该协议进行通信。
若你正在开发基于Rest架构的Python应用,你需要一个能与服务器通信的HTTP客户端。在很多情况下,这些客户端库由第三方,主要是独立开发者提供。使用第三方库可能会暴露你的安全风险,且整个应用的通信都将依赖于第三方。
对于Web应用,浏览器充当客户端库的角色,但对于非Web项目,则需依赖第三方客户端库。若考虑自行开发,需知这并非易事,且将增加维护另一应用的负担。
因此,为了解决Rest及客户端库的一些问题,Google在2015年推出了gRPC。
针对gRPC,Google维护了一个几乎支持所有流行语言的客户端库。它底层采用HTTP 2协议,并使用协议缓冲区(protobuf)作为消息格式。
你无需担心客户端库的维护,因为Google已为你处理,并支持几乎所有编程语言。单一且集中的客户端库是gRPC的一大优势。
gRPC的另一优势是其使用的消息格式。协议缓冲区是语言无关的,这意味着你可以用Python开发客户端,用Go开发服务器,两者仍能无障碍通信。
本质上,gRPC是一个客户端库和一个可在任何设备上使用的协议。
何为gRPC?
gRPC采用protobuf进行通信,将proto文件序列化为二进制格式后发送至服务器,服务器端再将其反序列化为原始格式。这就是gRPC与protobuf的工作机制。
gRPC提供了多种通信方式,可视为其特色功能。
gRPC的特色功能包括:
- 单一请求:这是一种简单的请求-响应交互模式,客户端发送proto请求,服务器接收后,经过一段时间处理,再返回响应。
- 服务器流式响应:客户端发起一次请求后,服务器会连续发送大量数据作为回应。例如,点击视频时,服务器会涌出大量视频相关数据。
- 客户端流式请求:与服务器流式响应相反,客户端一次性向服务器发送大量数据。例如,在互联网上分享大文件或上传图片、视频时,客户端持续向服务器发送数据。
- 双向流式通信:在这种通信模式下,客户端和服务器可以互发多条消息。聊天应用便是其典型实例。
这四大流行功能使得gRPC异常强大。
何时使用gRPC
关于gRPC的特点,我们看到了一些应用案例。设想你想要开发一个聊天应用。你不会选择使用Rest API,因为它无法支持快速的双向流通信。为此,我们将采用gRPC流,它除了速度外,还提供其他一些优势。
首先,其语言无关性意味着无论服务器或其他客户端使用何种编程语言编写,只要消息格式被接受,通信就能建立。
因此,利用这一特性,聊天应用的Android版本可以与iOS版本互通,反之亦然。
gRPC的问题
任何事物都存在问题,gRPC也不例外。
- 浏览器支持有限:由于gRPC使用HTTP 2,因此很难直接从浏览器调用gRPC服务,有时需要设置代理。
- 不可读格式:众所周知,gRPC采用二进制格式,对人类不友好。这在某些情况下是个缺点。
- 成熟度不足:gRPC自2015年开发以来,相比REST仍显稚嫩,许多bug和问题有待解决。
- 学习难度:Rest和GraphQL使用JSON,更易于学习。大多数人倾向于坚持使用它们,因为protobuf仍是一个新颖且复杂的主题,寻找gRPC专家较为困难。
REST与gRPC对比:
现在我们将探讨REST与gRPC之间的技术差异。
消息格式:
REST 主要使用 JSON(有时是 XML 格式)作为消息格式,这种格式更易于阅读和处理。在 Rest 中,您无需担心模式问题。相比之下,gRPC 使用协议缓冲区来序列化数据。其压缩形式更为轻量,传输速度更快。由于是二进制格式,因此它在传输过程中会序列化和反序列化数据。
HTTP 1.1 与 HTTP 2:
REST API 通常采用 HTTP 1.1 作为其协议,而 gRPC 则在底层使用 HTTP 2。尽管 REST API 仍可使用 HTTP 2,但由于请求-响应机制的限制,其功能受限。gRPC 利用 HTTP 2 支持客户端响应和双向通信的优势,这是 gRPC 性能优于 REST 的另一个方面。它既能处理 HTTP 1.1 式的单向请求,又能同时处理 HTTP 2 式的双向请求。
延迟:
gRPC 在通信中展现出的低延迟和高速度,使其在连接轻量级微服务架构系统时尤为有用,显著提升了消息传输效率。在多数网络情况下,REST 的延迟约为 25 毫秒,而 gRPC 的延迟远低于 REST。
负载限制:
REST 在发送出站消息时,最大负载限制为 45MB,而 gRPC 则没有此类限制,意味着您的出站消息可以尽可能大。
安全性:
在安全性方面,REST会显得落后,因为它使用HTTP 1.1和JSON格式,这些内容容易被解密和访问。相比之下,gRPC采用HTTP 2,安全性更高,且使用protobuf,这是一种二进制格式,难以被解密。
速度:
在这方面,gRPC同样占优,它提供的速度是REST的10倍,这同样得益于使用HTTP 2协议和protobuf消息格式。
代码生成功能
REST本身不提供内置的代码生成功能,这意味着开发者需要依赖第三方应用来生成API代码。而gRPC由于其protobuf编译器,具备原生的代码生成功能,且兼容多种编程语言。这对于微服务架构来说是一个额外的优势。
孟菲斯REST网关
为了通过HTTP调用实现消息生产,满足多种使用场景并简化操作,孟菲斯添加了一个HTTP网关,用于接收基于REST的请求(即消息),并将这些消息发送到指定的站点。
常见的受益于REST网关的使用场景包括:
- 直接从前端生成事件
- 通过HTTP服务器连接Debezium
- ArgoCD的Webhooks
- PostHog集成
- 通过HTTP调用从Fivetran/Rivery/任何ETL平台接收数据
孟菲斯REST网关加上JSON模式可以形成一个强大的组合,以提高数据质量并确保应用程序或服务之间的健康通信。
孟菲斯不久也将支持gRPC。
结论
总而言之,我想说的是REST仍然是使用最广泛且最受欢迎的架构,其地位难以被取代。尽管REST存在一些缺点,如缺乏数据流支持、无法实现双向通信、速度较慢等,但它对于日常生活中的标准应用程序而言,仍是最佳选择。
另一方面,尽管gRPC相对年轻且学习难度较大,但它提供了众多优势,如客户端和服务器端的高速数据流、良好的双向数据流支持、快速且紧凑,以及采用HTTP 2协议。由于其出色的性能,gRPC特别适合处理高负载应用,如视频流、音乐流、在线游戏、文件共享和聊天应用。