Rust 构建开源 Pingora 框架可以与nginx媲美

一、概述

Cloudflare 为何弃用 Nginx,选择使用 Rust 重新构建新的代理 Pingora 框架。Cloudflare 成立于2010年,是一家领先的云服务提供商,专注于内容分发网络(CDN)和分布式域名解析。它提供一系列安全和性能优化服务,包括防火墙、DDoS防护、SSL/TLS加密和威胁分析。

二、Pingora 介绍

Pingora 是一个基于 Rust 语言的框架,用于构建快速、可靠且可编程的网络系统。日处理请求量超 1万亿次,不仅在性能显著提升,且仅需原代理基础设施三分之一的 CPU 和内存资源。

三、Nginx 在当今需求下遇到的瓶颈

随着 Cloudflare 规模的扩大,已经超越了 Nginx 的处理能力了,无法满足当下所需要的性能,Nginx 也没有在非常复杂的环境中有所需要的功能。

虽然这些年来,Cloudflare 有对 Nginx 的使用遇到了部分限制,进行了优化,但是仍然有一些限制则更难克服,如下:

首先,在 Nginx 中,每个请求只能由单个 worker 处理,这样很容易导致所有 CPU 内核之间的负载不平衡,从而导致速度变慢。由于这种请求进程锁定效应,执行 CPU 繁重或阻止 IO 任务的请求可能会减慢其他请求的速度。

对于这些问题,花了很多时间来解决,但是对于 Cloudflare 规模的用例来说,最关键的问题是糟糕的连接重用。机器与原始服务器建立 TCP 连接,以代理 HTTP 请求,连接重用通过重用之前从连接池建立的连接,跳过新连接所需的 TCP 和 TLS 握手,来加快请求的 TTFB。

但是,Nginx 连接池与单个 worker 相对应,当请求到达某个 worker 时,它只能重用该 worker 内的连接。当添加更多 Nginx worker 以进行扩展时,连接重用率会变得更差,因为连接分散在所有进程的更多孤立的池中。这导致更慢的 TTFB 以及需要维护更多连接,进而消耗更多的资源。
在这里插入图片描述

除上述,Nginx 还面临有些类型的功能难以添加问题

Nginx 是一个非常好的 Web 服务器、负载均衡器或简单的网关。但对于 Cloudflare 的作用远不止于此。团队过去常常围绕 Nginx 构建自己需要的所有功能,但要尽量避免与 Nginx 上游代码库有太多分歧,不是一件很容易事情。

例如,当重试请求/请求失败时,将请求重定向到具有不同请求头的目标服务器,但 Nginx 并不支持这种操作,这要求人力投入额外的努力来克服其限制,这种情况下,还需要额外花费时间和精力来解决 Nginx 的限制。

其次,Nginx 是用C语言编写的,在设计上并非内存安全,增加了出错的风险,而且使用第三方代码库非常容易出错。 即使对于经验丰富的工程师来说,也很容易陷入内存安全问题,未来希望尽可能避免这些问题。

为了补充C语言,选择使用了 Lua,它相对安全但性能较低。 在处理复杂的 Lua 代码时,经常怀念静态类型的便利,而且 Nginx 社区的活跃度不高 ,开发过程往往较为封闭。

四、Pingora 项目设计决定

为了打造一个每秒提供数百万次请求且快速、高效和安全的代理,必须首先做出一些重要的设计决
定。设计核心如下:

选择 Rust 语言: 因为它可以在不影响性能的情况下以内存安全的方式完成 C 语言可以做的事情。

自建 HTTP 库: 选择自建的 HTTP 库而非现成的第三方库,以提高处理HTTP流量的灵活性和自主创新的能力。

支持多样化、不符合 RFC 的HTTP流量: 由于Cloudflare需要支持各种不符合RFC标准的HTTP流量,Pingora设计为一个稳健、宽容、可定制的HTTP库,以适应互联网各种风险环境和不规范的用例。

处理非标准的HTTP状态码: 为了应对服务器支持使用599到999之间的状态代码,Pingora实现了一个稳健的HTTP状态码处理系统,以适应不同HTTP生态系统中的多样性。

多线程工作负载调度: Pingora选择了多线程而不是多进程,以便轻松共享资源,特别是连接池。采用Tokio异步运行时来避免性能问题,并实施了工作窃取以提高效率。

基于请求生命周期的可编程接口: 实施了类似于NGINX/OpenResty的基于“请求生命周期”事件的可编程接口。这使得开发人员能够通过编写代码在请求的不同阶段进行干预,例如在请求标头接收时修改或拒绝请求,从而清晰地分离业务逻辑和通用代理逻辑。

五、很完美,Pingora 在生产中更快

Pingora 处理几乎所有需要与源服务器交互的 HTTP 请求(例如缓存未命中),在此过程中收集了很多性能数据。

首先,看到 Pingora 如何加快客户的流量,Pingora 上的总体流量显示,TTFB 中位数减少了 5 毫秒,第 95 个百分位数减少了 80 毫秒。这不是因为运行代码更快。甚至之前的旧服务也可以处理亚毫秒范围内的请求。

时间节省来自新架构,它可以跨所有线程共享连接,这意味着更好的连接重用率,在 TCP 和 TLS 握手上花费的时间更少。
在这里插入图片描述
在所有客户中,与旧服务相比,Pingora 每秒的新连接数只有三分之一。对于一个主要客户,它将连接重用率从 87.1% 提高到 99.92%,这将新连接减少了 160 倍。更直观地说,通过切换到 Pingora,每天为客户和用户节省了 434 年的握手时间。

六、Pingora 功能亮点

  • 异步 Rust 快速且可靠
  • HTTP 1/2 端到端代理
  • 基于 OpenSSL 或 BoringSSL 的 TLS
  • gRPC 和 websocket 代理
  • 优雅的重载
  • 可定制的负载平衡和故障转移策略
  • 支持多种观测工具

七、Pingora 生产环境后的反馈

更高效

在生产环境中,与我们的旧服务相比,Pingora 在相同流量负载的情况下,消耗的 CPU 和内存减少了约 70% 和 67%。以及多线程模型还使得跨请求共享数据更加高效。

更安全

像我们这样的规模下,快速安全的发布功能十分困难。很难预测在每秒处理数百万个请求的分布式环境中可能发生的每个边缘情况。Rust 的内存安全特性为我们提供了强大的保护,让我们能够信赖服务的稳定运行。更能够专注于服务间的交互,加速功能开发,无需担忧内存安全问题。

即便出现崩溃,Pingora 的稳定性也显著降低诊断难度。自推出以来,尽管处理了海量请求,但服务代码尚未导致任何崩溃,显示出其卓越的可靠性。

所以,Pingora 的崩溃极为罕见,问题往往与内核或硬件故障无关。即便在极端调试困难的情况下,软件也未导致过崩溃。

从中,我们可以看到 Rust 逐渐进入生产环境中,而且取得了很不错的效果,也相信未来 AI 领域,Rust 一定会带来很多资源节省、性能的提升及安全等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/463876.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Figure 01掀起了具身智能的崭新篇章

在人工智能的发展历程中,OpenAI始终扮演着创新的先锋角色。最近,他们与Figure公司的合作成果尤为引人注目,这一合作将多模态大模型技术成功应用于Figure 01机器人的开发中,为人类与机器的互动开辟了全新的时代。该机器人不仅能够与…

innovus中path group 的策略和应用(上)

在所有的后端工具里边,有三个重要的引擎:auto-place,CTS,auto-route三个。这里边的auto-place是决断了整个设计时序的基点。由于,auto-place的动作是在设计的preCTS阶段,所以这里的设计时序就是广义上说的&…

HDFSDATANODE数据传输详解

本文主要阐述datanode中一个socket连接接收字节流的构成,帮助datanode的接收与处理数据。注意hadoop版本为3.1.1。 写在前面 Datanode本质上也是TCPServer,一般的TCPServer接到客户端请求以后会分配一个线程处理,对于Datanode而言&#xff…

npm、nodejs和vue之间关系和区别介绍

本文讲解npm、Node.js和Vue.js这三者之间的关系和区别,以及它们各自的特点。 首先,让我们来了解一下Node.js。 **Node.js** 是一个开源的服务器端运行环境,它允许开发者使用JavaScript来编写服务器端的代码。在传统的Web开发中&#…

[ROS 系列学习教程] rosbag Python API

ROS 系列学习教程(总目录) 本文目录 1. 构造函数与关闭文件2. 属性值3. 写bag文件内容4. 读bag文件内容5. 将bag文件缓存写入磁盘6. 重建 bag 文件索引7. 获取bag文件的压缩信息8. 获取bag文件的消息数量9. 获取bag文件记录的起止时间10. 获取话题信息与消息类型 rosbag 的 Pyt…

【Java探索之旅】运算符解密 位运算,移位运算

🎥 屿小夏 : 个人主页 🔥个人专栏 : Java入门到精通 🌄 莫道桑榆晚,为霞尚满天! 文章目录 📑前言一、位运算符1.1 按位与 &1.2 按位或 |1.3 按位取反 ~1.4 按位异或^ 二、移位运…

快速排序算法,简洁,易懂

目录 代码实现(java): 一、首元素作为基准值 图: ​编辑 基本思路: 代码: 代码补充说明: 二、中间元素作为基准值 代码: 参考学习文章: 今天我们不刷力扣了,…

Java Web项目—餐饮管理系统Day07-套餐管理(二)

文章目录 1. 套餐的分页查询2. 更新套餐![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/209298cf3b4349c5a2fed56a3d33350e.png)第一步, 依据套餐id查询到套餐的基本信息以及关联菜品信息.第2步, 将请求数据进行保存(更新). 3. 批量的停售启售 这部分开发剩下的部分…

CSS Module

CSS Module的作用:将CSS样式作用域限制在特定的组件范围内,以避免全局样式污染和命名冲突。 Vue中如何实现样式模块…

SVN修改已提交版本的注释

目录 一、需求分析 二、问题分析 三、解决办法 一、需求分析 ​开发过程中,在SVN提交文件后,发现注释写的不完整或不够明确,想再修改之前的注释文字​。 使用环境: SVN服务器操作系统:Ubuntu 20.04.6 LTS SVN版本&…

物理隔离条件下,如何安全高效地进行内外网文件导入导出?

内外网文件导入导出通常指的是在内部网络(内网)和外部网络(外网)之间传输文件的过程。这在企业环境中尤其常见,因为内部网络通常包含敏感数据,而外部网络(如互联网)则允许更广泛的访…

计算机网络实验——学习记录

1. tun/tap模块:为Linux系统提供网络虚拟功能,tun位于网络OSI模型的三层(网络层),tap位于网络的二层(数据链路层)。 1.1 验证是否包含tun/tap模块:modinfo tun; 1.2 验…

8:00面试,8:06就出来了,问的问题有点变态。。。

从小厂出来,没想到在另一家公司又寄了。 到这家公司开始上班,加班是每天必不可少的,看在钱给的比较多的份上,就不太计较了。没想到9月一纸通知,所有人不准加班,加班费不仅没有了,薪资还要降40%…

echarts散点图自定义tooltip,鼠标放上去展示多行数据

先放效果图 如图,就是鼠标悬停在散点上(这里的散点我替换成了图片,具体做法参考这篇文章:echarts散点图的散点用自定义图片替代-CSDN博客)时,可以展示多行数据。之前查找资料的时候,很多用字符串…

封装哈希表

本文旨在讲解哈希表的封装,我们以哈希桶的结构来进行封装unorderedmap/set。要想实现封装哈希表,我们首先得先将哈希表的结构给搭建出来,然后再根据哈希桶的结构进一步封装unorderedmap/set! 下面我们先来实现哈希桶的结构&#x…

12_Linux内核结构

Linux内核结构 1.内核的主要组成部分 Linux 内核主要的 5 个部分:进程调度、内存管理、虚拟文件系统、网络接口、进程通信。在系统移植的时候,它们是内核的基本元素,这 5 个部分之间的关系,如图所示: 进程调度&#…

V-JEPA模型,非LLM另外的选择,AGI的未来:迈向Yann LeCun先进机器智能(AMI)愿景的下一步

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

小怂爱水洼DFS

分析: 非常明显的搜索问题,当时我在写的时候遇到了两个问题,就一直没过。 1.忘记判断临界条件,x,t不能越界的问题; 2.最后有两个案例一直不能过,就是因为我用的int型的接受结果范围太小了&#…

前端学习从0到1第一天:初见html

阅读须知: 探索者安全团队技术文章仅供参考,未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作,由于传播、利用本公众号所提供的技术和信息而造成的任何直接或者间接的后果及损失,均由使用者 本人负责,作者不为此承担任何责任,如…

【C++中日期类的实现】

一路,一路,一路从泥泞到风景............................................................................................... 目录 前言 一、【什么是日期类】 二、【代码实现】 1.【Date.h】部分: 2.【Date.cpp】部分:…