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


继续投资 NGINX,向其付款进行定制,使其 100% 满足我们的需求 。我们拥有所需的专业知识,但鉴于上述架构限制,需要付出大量努力才能以完全支持我们需求的方式重建它 。
迁移到另一个第三方代理代码库 。肯定有好的项目,比如 envoy 和其他一些 。但这条道路意味着在几年内可能会重复同样的循环 。
从头开始建立一个内部平台和框架 。这一选择需要在工程方面进行最大的前期投资 。
在过去的几年中,我们每个季度都会对这些选项进行评估 。没有明显的公式来判断哪种选择是最好的 。在几年的时间里,我们继续走阻力最小的道路,继续增强 NGINX 。然而 , 在某些情况下,建立自有代理的投资回报率似乎更值得 。我们呼吁从头开始建立一个代理,并开始设计我们梦想中的代理应用程序 。
Pingora 项目设计决定
为了打造一个每秒提供数百万次请求且快速、高效和安全的代理,我们必须首先做出一些重要的设计决定 。
我们选择 Rust 作为项目的语言 , 因为它可以在不影响性能的情况下以内存安全的方式完成 C 语言可以做的事情 。
尽管有一些很棒的现成第 3 方 HTTP 库,例如 hyper,我们选择构建自己的库是因为我们希望最大限度地提高处理 HTTP 流量的灵活性 , 并确保我们可以按照自己的节奏进行创新 。
在 Cloudflare,我们处理整个互联网的流量 。我们必须支持许多奇怪且不符合 RFC 的 HTTP 流量案例 。这是 HTTP 社区和 Web 中的一个常见困境,在严格遵循 HTTP 规范 , 和适应潜在遗留客户端或服务器的广泛生态系统的细微差别之间存在矛盾和冲突 , 需要在其中作出艰难抉择 。
HTTP 状态码在 RFC 9110 中定义为一个三位整数,通常预期在 100 到 599 的范围内 。Hyper 就是这样一种实现 。但是,许多服务器支持使用 599 到 999 之间的状态代码 。我们为此功能创建了一个问题 , 探讨了争论的各个方面 。虽然 hyper 团队最终确实接受了这一更改,但他们有充分的理由拒绝这样的要求,而这只是我们需要支持的众多不合规行为案例之一 。
为了满足 Cloudflare 在 HTTP 生态系统中的地位要求 , 我们需要一个稳健、宽容、可定制的 HTTP 库,该库可以在互联网的各种风险环境中生存,并支持各种不合规的用例 。保证这一点的最佳方法就是实施我们自己的架构 。
下一个设计决策关于我们的工作负载调度系统 。我们选择多线程而不是多处理,以便轻松共享资源,尤其是连接池 。我们认为还需要实施工作窃取来避免上面提到的某些类别的性能问题 。Tokio 异步运行时结果非常适合我们的需求 。
最后,我们希望我们的项目直观且对开发人员友好 。我们构建的不是最终产品,而是应该可以作为一个平台进行扩展,因为在它之上构建了更多的功能 。
我们决定实施一个类似于 NGINX/OpenResty 的基于“请求生命周期”事件的可编程接口 。例如,“请求过滤器”阶段允许开发人员在收到请求标头时运行代码来修改或拒绝请求 。通过这种设计,我们可以清晰地分离我们的业务逻辑和通用代理逻辑 。之前从事 NGINX 工作的开发人员可以轻松切换到 Pingora 并迅速提高工作效率 。
Pingora 在生产中更快
让我们快进到现在 。Pingora 处理几乎所有需要与源服务器交互的 HTTP 请求(例如缓存未命中),我们在此过程中收集了很多性能数据 。
首先,让我们看看 Pingora 如何加快我们客户的流量 。Pingora 上的总体流量显示,TTFB 中位数减少了 5 毫秒,第 95 个百分位数减少了 80 毫秒 。这不是因为我们运行代码更快 。甚至我们的旧服务也可以处理亚毫秒范围内的请求 。
时间节省来自我们的新架构,它可以跨所有线程共享连接 。这意味着更好的连接重用率,在 TCP 和 TLS 握手上花费的时间更少 。

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

文章插图
在所有客户中 , 与旧服务相比,Pingora 每秒的新连接数只有三分之一 。对于一个主要客户,它将连接重用率从 87.1% 提高到 99.92%,这将新连接减少了 160 倍 。更直观地说,通过切换到 Pingora , 我们每天为客户和用户节省了 434 年的握手时间 。ChatGPT中文网站:https://AI.cxyquan.com/   
更多功能 拥有工程师熟悉的开发人员友好界面,同时消除以前的限制,让我们能够更快地开发更多功能 。像新协议这样的核心功能充当我们为客户提供更多产品的基石 。


推荐阅读