Cloudflare 在 2020 生日周期间推出了对 gRPC® 的支持。我们对测试版的巨大兴趣感到非常荣幸,我们要感谢每一个申请并试用 gRPC 的人!在这篇文章中,我们将深入探讨我们如何实现支持的技术细节。在这篇文章中,我们将深入探讨我们如何实现支持的技术细节。
什么是gRPC?
gRPC是一个运行在HTTP/2上的开源RPC框架。RPC(远程过程调用)是一台机器告诉另一台机器做某事的方式,而不是调用库中的本地函数。在分布式计算的历史上,RPC已经存在了很长时间,不同的实现专注于不同的领域。gRPC的独特之处在于以下几个特点。
- 它需要现代的HTTP/2协议进行传输,现在已经广泛使用。
- 完整的客户端/服务器参考实现、演示和测试套件都是开源的。
- 它没有指定消息格式,尽管协议缓冲区是首选的序列化机制。
- 客户端和服务器都可以流式传输数据,这就避免了需要轮询新数据或创建新的连接。
在协议方面,gRPC广泛使用HTTP/2帧:请求和响应看起来与正常的HTTP/2请求非常相似。
然而,不寻常的是gRPC对HTTP trailer的使用。虽然它并没有在野外广泛使用,但HTTP trailers从1999年开始就已经存在了,正如最初的HTTP/1.1 RFC2616所定义的那样。HTTP消息头被定义在HTTP消息体之前,但HTTP trailer是一组可以附加在消息体之后的HTTP头。然而,由于trailer的用例不多,所以很多服务器和客户端的实现并不完全支持trailer。而HTTP/1.1需要使用分块传输编码来发送HTTP trailer,在HTTP/2的情况下,trailer是在正文的DATA帧之后的HEADER帧。
有些情况下,HTTP trailer是有用的。例如,我们使用HTTP响应码来表示请求的状态,但响应码是HTTP响应的第一行,所以我们需要很早就决定响应码。trailer使得我们可以在正文之后发送一些元数据。例如,假设你的Web服务器发送了一个大数据流(这个数据流不是固定大小的),最后你想发送一个你发送的数据的SHA256校验码,这样客户端就可以验证内容。通常情况下,使用HTTP状态码或响应头是不可能的,因为响应头应该在响应的开头发送。使用HTTP trailer头,你可以在发送完所有数据后再发送另一个头(如Digest)。
gRPC使用HTTP trailer有两个目的。首先,它在发送完内容后,将其最终状态(grpc-status)作为trailer发送。第二个原因是为了支持流式用例。这些用例比普通的HTTP请求持续的时间要长得多。HTTP trailer用于给出请求或响应的后处理结果。例如如果在流式数据处理过程中出现了错误,可以使用trailer发送错误代码,而在消息体之前的头是不可能的。
下面是一个简单的HTTP/2帧的gRPC请求和响应的例子。
在Cloudflare Edge上添加gRPC支持。
由于gRPC使用HTTP/2,听起来很容易原生支持gRPC,因为Cloudflare已经支持HTTP/2。然而,我们遇到了几个问题。
- 我们的边缘代理不完全支持HTTP请求/响应trailer。Cloudflare使用NGINX接受来自眼球的流量,它对trailer的支持有限。进一步复杂化的是,流经Cloudflare的请求和响应要经过一组其他代理。
- HTTP/2到原点:我们的边缘代理使用HTTP/1.1从原点获取对象(无论是动态还是静态)。为了代理gRPC流量,我们需要支持使用HTTP/2连接到客户gRPC原点。
- gRPC流需要允许双向请求/响应流:gRPC有两种协议流,一种是单利流,即简单的请求和响应,另一种是流式流,允许每个方向不间断的数据流。为了完全支持流式传输,HTTP消息体需要在收到另一端的响应头后再发送。例如,客户端流媒体在收到响应头后会一直发送请求体。
由于这些原因,当通过我们的网络代理时,gRPC请求会中断。为了克服这些限制,我们研究了各种解决方案。例如,NGINX有一个gRPC上游模块来支持HTTP/2 gRPC原点,但它是一个单独的模块,而且它还需要HTTP/2下游,这不能用于我们的服务,因为请求在某些情况下会通过多个HTTP代理级联。在管道中处处使用HTTP/2是不现实的,因为我们内部负载均衡架构的特点,而且要确保所有的内部流量都使用HTTP/2会花费太多精力。
转换到HTTP/1.1?
最终,我们发现了一个更好的方法:在我们的网络内部将gRPC消息转换为没有trailer的HTTP/1.1消息,然后在将请求发送至原点之前将其转换回HTTP/2。这将适用于Cloudflare内部大多数不支持HTTP trailer的HTTP代理,而且我们需要的改动也很小。
gRPC社区并没有发明我们自己的格式,而是已经提出了一个兼容HTTP/1.1的版本:gRPC-web。gRPC-web是对原来基于HTTP/2的gRPC规范的修改。最初的目的是为了与缺乏直接访问HTTP/2帧的Web浏览器配合使用。有了gRPC-web,HTTP trailer被移到了正文中,所以我们不需要担心代理服务器内部对HTTP trailer的支持。它还带有流媒体支持。由此产生的HTTP/1.1消息仍然可以被我们的安全产品(如WAF和Bot管理)检查,以提供与Cloudflare为其他HTTP流量带来的相同级别的安全性。
当Cloudflare的边缘代理收到HTTP/2 gRPC消息时,该消息会被 "转换 "为HTTP/1.1 gRPC-web格式。一旦gRPC消息被转换,它就会通过我们的管道,以与任何正常的HTTP请求相同的方式应用服务,如WAF、Cache和Argo服务。
就在gRPC-web消息离开Cloudflare网络之前,它需要再次被 "转换 "回HTTP/2 gRPC。被我们系统转换的请求会被标记,这样我们的系统就不会意外地转换源自客户端的gRPC-web流量。
HTTP/2起源支持
工程上的挑战之一是支持使用HTTP/2连接到origins。在这个项目之前,Cloudflare并不具备通过HTTP/2连接到起源的能力。
因此,我们决定在内部构建对HTTP/2原点的支持。我们构建了一个独立的起源代理,能够通过HTTP/2连接到起源。在这个新平台之上,我们实现了gRPC的转换逻辑。gRPC支持是利用这个新平台的第一个功能。对HTTP/2连接到起源服务器的更广泛的支持已经在路线图上。
gRPC流媒体支持
如上所述,gRPC有一个流模式,请求体或响应体可以以流的形式发送;在gRPC请求的生命期内,gRPC消息块可以随时发送。在流的最后,会有一个HEADER帧表示流的结束。当它转换为gRPC-web时,我们会使用分块编码发送body,并保持连接开放,接受body的两边,直到得到一个gRPC消息块,表示流的结束。这就要求我们的代理支持双向传输。
例如,客户端流是一种有趣的模式,服务器已经响应了响应代码及其头,但客户端仍然能够发送请求体。
互操作性测试
Cloudflare的每个新功能在发布前都需要进行适当的测试。在最初的开发过程中,我们使用了带有gRPC-web过滤功能的envoy代理和gRPC的官方示例。我们准备了一个带有envoy和gRPC测试原点的测试环境,以确保边缘代理在gRPC请求下正常工作。来自gRPC测试客户端的请求被发送到边缘代理并转换为gRPC-web,然后转发给envoy代理。之后,envoy转换回gRPC请求,并发送至gRPC测试原点。我们能够通过这种方式来验证基本行为。
一旦我们准备好了基本功能,我们还需要确保两端的转换功能能够正常工作。为此,我们建立了更深层次的互操作性测试。
我们将现有的gRPC互操作性测试用例引用到我们的测试套件中,并在本地运行边缘代理和新的原点代理之间的第一次迭代测试。
在第二次迭代测试中,我们使用了不同的gRPC实现。例如,一些服务器在出现即时错误时,会在仅有trailer的响应中发送他们的最终状态(grpc-status)。这个响应将包含HTTP/2响应头和trailer在一个单一的HEADERS帧块中,同时设置END_STREAM和END_HEADERS标志。其他的实现则是将最终的状态作为trailer发送到一个单独的HEADERS帧中。
在本地验证了互操作性之后,我们在支持生产中所有服务的开发环境中运行了测试线束。然后,我们能够确保没有意外的副作用影响到gRPC请求。
我们喜欢吃狗食 我们成功部署边缘 gRPC 支持的首批服务之一是 Cloudflare drand 随机性信标。入职很简单,过去几周我们一直在生产中运行该信标,没有出现任何问题。
结论
支持新协议是一项令人兴奋的工作 在现有系统中实施对新技术的支持是令人兴奋和复杂的,通常涉及实施速度和整体系统复杂性之间的权衡。在 gRPC 的情况下,我们能够以不需要对 Cloudflare 边缘进行重大更改的方式快速构建支持。在确定在 HTTP/2 gRPC 和 HTTP/1.1 gRPC-web 格式之间转换的想法之前,我们仔细考虑了实施方案,从而实现了这一目标。这种设计选择使服务集成更快、更容易,同时还能满足我们用户的期望和约束。
如果你对使用Cloudflare来保证gRPC服务的安全和加速感兴趣,你可以在这里阅读更多信息。如果你想从事像本文所述的有趣的工程挑战,请提出申请
gRPC®是Linux基金会的注册商标。
通过www.DeepL.com/Translator(免费版)翻译
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!