【通讯协议】HTTP/2和GRPC:微服务通信的事实标准
视频号
微信公众号
知识星球
HTTP/2和gRPC允许微服务之间更快、更简单、更健壮的通信。但你有没有想过,我们为什么要使用这种技术堆栈,他们为什么要发明HTTP/2和gRPC?
在本文中,让我们看看HTTP/2与HTTP/1.x的主要区别是什么,它解决了什么问题,以及gRPC如何在后台利用HTTP/2并利用HTTP/2的所有效率。
HTTP协议背景
应用层是开放系统互连(OSI)模型中的最顶层,即第7层。应用层有许多网络协议,HTTP就是其中之一。
HTTP/1.1
HTTP/1.1是1989年作为万维网的通信标准开发的。HTTP使用类似GET POST或DELETE的方法来指定客户端希望对资源执行的操作。
例如,假设您正在访问www.example.com网站。当您导航到此URL时,web浏览器会以基于文本的消息的形式发送HTTP请求。
响应此请求,除了HTML中调用的任何图像、样式表或其他资源外,Web服务器还会向请求客户端返回一个HTML页面。请注意,在第一次数据调用中,并不是所有的资源都返回给客户端。请求和响应将在服务器和客户端之间来回发送,直到web浏览器收到在屏幕上呈现HTML页面内容所需的所有资源。
HTTP/2
HTTP/2于2015年5月发布。从技术角度来看,区分HTTP/1.1和HTTP/2的最重要特征之一是二进制成帧层。与将所有请求和响应保持为纯文本格式的HTTP/1.1不同,HTTP/2使用二进制框架层以二进制格式封装所有消息,同时仍然保持HTTP语义,如谓词、方法和标头。应用程序级API仍会以传统HTTP格式创建消息,但底层会将这些消息转换为二进制。这确保了在HTTP/2之前创建的web应用程序在与新协议交互时可以继续正常运行。
因此,HTTP/1.1和HTTP/2共享语义,确保在这两种协议中服务器和客户端之间传输的请求和响应以具有头和体的传统格式化消息的形式到达目的地,使用GET和POST等熟悉的方法。在下一节中,让我们看看HTTP/1.1如何尝试通过其交付模型优化效率,以及由此产生的问题,然后是HTTP/2的二进制帧层的优势,以及它如何对请求进行优先级排序的描述。
HTTP/1.1问题
Pipelining和线路堵塞头
客户端在HTTPGET请求上收到的第一个响应通常不是完全呈现的页面。相反,它包含指向请求页面所需的其他资源的链接。客户端发现,只有在下载页面后,页面的完整呈现才需要服务器提供这些额外资源。因此,客户端将不得不发出额外的请求来检索这些资源。在HTTP/1.0中,客户端必须断开并重新建立每一个新请求的TCP连接,这在时间和资源方面都是一件代价高昂的事情。
HTTP/1.1通过引入持久连接和流水线来解决这个问题。对于持久连接,HTTP/1.1假设TCP连接应该保持打开,除非直接通知关闭,这大大提高了重新建立TCP连接的成本。通过流水线,客户端可以沿着同一连接一个接一个地发送请求,而无需等待对每个请求的响应。
但是,服务器仍然需要按照传入请求的顺序发送响应。因此HTTP/1.1仍然是一个FIFO队列,在某些情况下,位于队列头部的请求无法检索其所需的资源,将阻塞其后面的所有请求。这被称为行头(HOL)阻塞。添加单独的并行TCP连接可能有助于解决此问题,但客户端和服务器之间可能存在的并发TCP连接数量有限,并且每个新连接都需要大量资源,这与HTTP/1.0的问题相同。
HTTP/2的创建就是为了解决这些问题。让我们看看使用二进制帧层可以如何解决这些问题。
HTTP/2和HTTP/1.x之间的主要区别
二进制成帧层
在HTTP/2连接中,存在多个数据流。每个流都由熟悉的请求/响应格式的多条消息组成。
这些消息中的每一条都被拆分为称为帧的较小单元。
在最细粒度的层面上,通信信道由一堆二进制编码的帧组成,每个帧都标记到一个特定的流。识别标签允许连接在传输期间交错这些帧,并在另一端重新组装它们。交错的请求和响应可以并行运行,而不会阻塞它们后面的消息,这一过程称为多路复用。多路复用通过确保没有消息需要等待另一个消息完成,解决了HTTP/1.1中的行头阻塞问题。这也意味着服务器和客户端可以发送并发请求和响应,从而实现更大的控制和更高效的连接管理。
由于多路复用允许客户端并行构建多个流,因此这些流只需要使用单个TCP连接。通过减少整个网络的内存和处理占用,每个源拥有一个持久连接改进了HTTP/1.1。这导致了更好的网络和带宽利用率,从而降低了总体运营成本。
头压缩
每个HTTP传输都携带一组头,这些头描述了传输的资源及其属性。在HTTP/1.x中,此元数据始终以纯文本形式发送,每次传输会增加500-800字节的开销,如果使用HTTP cookie,则有时会增加千字节。为了减少这种开销并提高性能,HTTP/2使用HPACK压缩格式压缩请求和响应标头元数据。
除了压缩之外,客户端和服务器还维护一个常见字段及其压缩值的列表。因此,当这些字段被重复时,它们只是包括对压缩值的引用。
服务器推送
除了对原始请求的响应之外,服务器还可以向客户端推送额外的资源,而客户端不必显式地请求每个资源。
例如,当浏览器请求页面时,服务器会在响应中发送HTML,然后需要等待浏览器解析HTML并发出对所有嵌入资产的请求,然后才能开始发送JavaScript、图像和CSS。
服务器推送可能允许服务器通过将其认为客户端需要的响应“推送”到其缓存中来避免这种往返延迟。
然而,推动反应并不是“神奇的”——如果使用不当,可能会损害表现。正确使用服务器推送是一个正在进行的实验和研究领域。
总之,与HTTP/1.1相比,HTTP/2:
- 是二进制的,而不是文本的
- 完全多路复用,而不是有序和阻塞
- 因此可以使用一个连接进行并行
- 使用标头压缩来减少开销
- 允许服务器主动将响应“推送”到客户端缓存中
有关HTTP/2的更多详细信息,请访问HTTP2Spec和O'Reilly高性能浏览器网络。
现在您可能想知道HTTP/2和gRPC之间的关系是什么。gRPC使用HTTP/2作为其消息传递协议,因此它固有了HTTP/2的所有效率。在下一节中,让我们更详细地了解gRPC提供了哪些功能,并将其与其他通信类型进行比较。
微服务之间的通信
服务通过消息以同步或异步的方式相互通信。让我们看看服务间通信是如何发展的。
SOAP-简单对象访问协议
- 客户端和服务器以XML的形式交换数据
- 由于它的XML,它可以在完全独立于语言和平台的平台上实现。
- 可以通过HTTP、SMTP、TCP、UDP等任何协议进行操作。
- 至今仍存在于许多遗留服务中。
- 很难处理,有一套严格的编码规则。
- 协议的冗长、XML的解析速度慢以及缺乏标准化的交互模型,导致了更直接地使用HTTP协议的服务占主导地位。例如REST。
REST-重新呈现状态传输
- 交互(创建-读取-更新-删除)资源的标准方式。
- 公开API(URL)作为资源的访问点。
- 只能使用HTTP。
- 仅公开HTTP方法(POST、GET、PUT、PATCH和DELETE)上的CRUD行为。如果我们的需求与这些定义良好的规则稍有不同,我们需要调整这组名称以公开我们的API。
- 没有定义严格的接口类型。即使我们有OpenAPI或Swagger规范,它也没有与带下划线的体系结构或消息协议进行类型绑定。
gRPC-Google远程过程调用
- 由谷歌设计的开源RPC框架。
- 公开要远程调用的其他服务的过程。
- 最大的优点是它可以与HTTP/2协议一起工作,并且因此受益于HTTP/2的许多上述效率。
- 实现协议缓冲区或Protobuf,一种gRPC中的IDL(接口描述语言)。
- 现在,我们了解了几种流行的相互通信协议的背景和总体思想。让我们看看优缺点,以及为什么我们应该选择gRPC而不是REST来进行微服务通信。
gRPC vs REST
HTTP/1.1与HTTP/2
RESTAPI遵循通常基于HTTP1.1构建的请求-响应通信模型。不幸的是,这意味着,如果微服务从客户端接收到多个请求,则模型必须一次处理每个请求,从而降低整个系统的速度。然而,RESTAPI也可以建立在HTTP/2上,但通信的请求-响应模型保持不变,这使得RESTAPI无法充分利用HTTP2的优势,例如流通信和双向支持。
gRPC没有面临类似的障碍。它基于HTTP2构建,支持双向通信和流式通信。gRPC可以通过不断地流式传输信息来同时处理请求,同时也可以处理类似于基于HTTP1.1构建的“一元”交互。
有效载荷数据结构
如前所述,gRPC默认情况下使用协议缓冲区来序列化有效负载数据。此解决方案更轻,因为它启用了高度压缩的格式并减小了消息的大小。此外,Protobuf(或协议缓冲区)是二进制的;因此,它对结构化数据进行序列化和反序列化,以便进行通信和传输。换句话说,强类型消息可以自动从Protobuf转换为客户端和服务器的编程语言。
这可以减少从字符串转换为类型的许多错误,例如,客户端发送一个int64字段类型,该字段类型被转换为JSON字符串并发送到服务器,但服务器期望int32字段类型和各种错误都可能发生。
REST主要依靠JSON或XML格式来发送和接收数据。事实上,尽管JSON没有强制要求任何结构,但它是最流行的格式,因为它具有灵活性和发送动态数据的能力,而不必遵循严格的结构。使用JSON的另一个显著好处是它的可读性级别,Protobuf还无法与之竞争。
尽管如此,JSON在数据传输方面并没有那么轻量级或快速。原因在于,在使用REST时,JSON(或其他格式)必须序列化,并转换为客户端和服务器端使用的编程语言。这给传输数据的过程增加了额外的步骤和开销,从而可能损害性能并导致错误。
生成代码功能
与gRPC不同,REST API不提供内置代码生成功能,这意味着开发人员必须使用Swagger或Postman等第三方工具来为API请求生成代码。
相比之下,gRPC具有原生代码生成功能,因为它的协议编译器与几种编程语言兼容。这对于集成以不同语言和平台开发的各种服务的微服务系统尤其有益。
结论
在本文中,我们了解了HTTP/2,它为什么诞生,它解决了什么问题,与HTTP/1.x相比的关键差异,以及gRPC如何在后台利用HTTP/2并利用HTTP/2的所有效率。我们还比较了REST和gRPC,发现gRPC在性能、有效负载数据结构和本地生成代码的能力方面比REST有很多优势。这些原因使得HTTP/2和gRPC完全适合高性能、可靠性和健壮的微服务通信。
参考文献
- HTTP/1.1 vs HTTP/2: What’s the Difference? (digitalocean.com)
- HTTP/2 and gRPC — The Next Generation of Microservices Interactions (blog.netsil.com)
- Introduction to HTTP/2 (developers.google.com)
- HTTP/2 Frequently Asked Questions (http2.github.io)
- GRPC VS REST: COMPARING APIS ARCHITECTURAL STYLES (www.imaginarycloud.com)
- 137 次浏览