弃用 Nginx,他们选择这款工具!( 三 )


例如 , 我们能够在没有重大障碍的情况下向 Pingora 添加 HTTP/2 上游支持 。这使我们能够在不久之后向我们的客户提供 gRPC 。将相同的功能添加到 NGINX 将需要更多的工程工作,并且可能无法实现 。
最近,我们宣布推出了 Cache Reserve,其中 Pingora 使用 R2 存储作为缓存层 。随着我们向 Pingora 添加更多功能,我们能够提供以前不可行的新产品 。
更高效
在生产环境中,与我们的旧服务相比,Pingora 在相同流量负载的情况下,消耗的 CPU 和内存减少了约 70% 和 67% 。节省来自几个因素 。
与旧的 Lua 代码相比,我们的 Rust 代码运行效率更高 。最重要的是,它们的架构也存在效率差异 。例如 , 在 NGINX/OpenResty 中,当 Lua 代码想要访问 HTTP 头时,它必须从 NGINX C 结构中读取它,分配一个 Lua 字符串,然后将其复制到 Lua 字符串中 。之后,Lua 还对其新字符串进行垃圾回收 。在 Pingora 中,它只是一个直接的字符串访问 。
多线程模型还使得跨请求共享数据更加高效 。NGINX 也有共享内存,但由于实施限制,每次共享内存访问都必须使用互斥锁,并且只能将字符串和数字放入共享内存 。在 Pingora 中,大多数共享项目可以通过原子引用计数器后面的共享引用直接访问 。
如上所述 , CPU 节省的另一个重要部分是减少了新的连接 。与仅通过已建立的连接发送和接收数据相比,TLS 握手成本显然更为高昂 。
更安全
在我们这样的规模下,快速安全地发布功能十分困难 。很难预测在每秒处理数百万个请求的分布式环境中可能发生的每个边缘情况 。模糊测试和静态分析只能缓解这么多 。Rust 的内存安全语义保护我们免受未定义行为的影响,并让我们相信我们的服务将正确运行 。
有了这些保证,我们可以更多地关注我们的服务更改将如何与其他服务或客户来源进行交互 。我们能够以更高的节奏开发功能,而不用背负内存安全和难以诊断崩溃的问题 。
当崩溃确实发生时,工程师需要花时间来诊断它是如何发生的以及是什么原因造成的 。自 Pingora 创立以来,我们已经处理了数百万亿个请求,至今尚未因为我们的服务代码而崩溃 。
事实上 , Pingora 崩溃是如此罕见,当我们遇到一个问题时 , 我们通常会发现不相关的问题 。最近,我们的服务开始崩溃后不久,我们发现了一个内核错误 。我们还在一些机器上发现了硬件问题,过去排除了由我们的软件引起的罕见内存错误 , 即使在几乎不可能进行重大调试之后也是如此 。
总结总而言之,我们已经建立了一个更快、更高效、更通用的内部代理,作为我们当前和未来产品的平台 。
我们之后将介绍有关我们面临的问题和应用优化的更多技术细节,以及我们从构建 Pingora 并将其推出以支持互联网的重要部分的经验教训 。同时还将介绍我们的开源计划 。




推荐阅读