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 一定会带来很多资源节省、性能的提升及安全等。
相关文章:
Rust 构建开源 Pingora 框架可以与nginx媲美
一、概述 Cloudflare 为何弃用 Nginx,选择使用 Rust 重新构建新的代理 Pingora 框架。Cloudflare 成立于2010年,是一家领先的云服务提供商,专注于内容分发网络(CDN)和分布式域名解析。它提供一系列安全和性能优化服务…...
MediaCodec源码分析 ACodec状态详解
前言 本文分析ACodec状态机,ACodec是MediaCodec的底层实现,在MediaCodec命令下切换不同状态进行编解码,基于7.0代码。 ACodec状态介绍 UninitializedState:未初始化状态。 在业务层调用MediaCodec. createByCodecName 完成后切换到LoadedState。 LoadedState:表示解码器…...
【Elasticsearch】windows安装elasticsearch教程及遇到的坑
一、安装参考 1、安装参考:ES的安装使用(windows版) elasticsearch的下载地址:https://www.elastic.co/cn/downloads/elasticsearch ik分词器的下载地址:https://github.com/medcl/elasticsearch-analysis-ik/releases kibana可视化工具下载…...
如何快速搭建物联网工业云平台
随着物联网技术的快速发展,物联网工业云平台已经成为推动工业领域数字化转型的重要引擎。合沃作为专业的物联网云服务提供商,致力于为企业提供高效、可靠的物联网工业云平台解决方案。本文将深入探讨物联网工业云平台的功能、解决行业痛点的能力以及如何…...
Spring Data访问Elasticsearch----Elasticsearch对象映射
Spring Data访问Elasticsearch----Elasticsearch对象映射 一、元模型(Meta Model)对象映射1.1 映射注解概述1.1.1 控制向Elasticsearch写入和从其读取哪些属性1.1.2 日期格式映射1.1.3 Range类型1.1.4 映射的字段名1.1.5 Non-field-backed属性1.1.6 其他属性注解 1.2 映射规则1…...
Linux之shell循环
华子目录 for循环带列表的for循环格式分析示例shell允许用户指定for语句的步长,格式如下示例 不带列表的for循环示例 基于C语言风格的for循环格式示例注意 while循环格式示例 until循环作用格式示例 循环控制breakcontinue详细语法示例 循环嵌套示例 for循环 for循…...
Python入门教程(一)|基本语法概述
目录 1. 注释 2. 变量和数据类型 3. 控制流 4. 函数 5. 类与对象 6. 异常处理 7. 模块和包 8. 文件操作 1. 注释 在Python中,单行注释以#开始,多行注释使用三个引号 """ 或 。 # 这是单行注释""" 这是 多行 注释…...
Android Studio入门——页面跳转
1.工程目录 2.MainActivity package com.example.demo01;import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.TextView;import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCo…...
肝了三天,完成了AIGC工具网站大全,建议收藏再看
说是肝了三天,其实远远不止,前前后后,从资料搜集到最后整理成文,有近一个月了,大家看在整理不易的份上,给点个赞吧,不要光顾着收藏呀! 国内网站 AIGC 导航 https://www.aigc.cn 网…...
算法练习:前缀和
目录 1. 一维前缀和2. 二维前缀和3. 寻找数组中心下标4. 除自身以外数组的乘积5. !和为k的子数字6. !和可被k整除的子数组7. !连续数组8. 矩阵区域和 1. 一维前缀和 题目信息: 题目链接: 一维前缀和思路:求前缀和数组,sum dp[r] …...
Kafka MQ 生产者
Kafka MQ 生产者 生产者概览 尽管生产者 API 使用起来很简单,但消息的发送过程还是有点复杂的。图 3-1 展示了向 Kafka 发送消息的主要步骤。 我们从创建一个 ProducerRecord 对象开始,ProducerRecord 对象需要包含目标主题和要发送的内容。我们还可以…...
SQLiteC/C++接口详细介绍之sqlite3类(十)
返回目录:SQLite—免费开源数据库系列文章目录 上一篇:SQLiteC/C接口详细介绍之sqlite3类(九) 下一篇:SQLiteC/C接口详细介绍之sqlite3类(十一) 30.sqlite3_enable_load_extension&#x…...
Vue中nextTick一文详解
什么是 nextTick? 在 Vue 中,当我们修改数据时,Vue 会自动更新视图。但是,由于 JavaScript 的事件循环机制,我们无法立即得知视图更新完成的时机。这时候,我们就需要使用 nextTick 来获取视图更新完成后的…...
爱奇艺 CTR 场景下的 GPU 推理性能优化
01 背景介绍 GPU 目前大量应用在了爱奇艺深度学习平台上。GPU 拥有成百上千个处理核心,能够并行的执行大量指令,非常适合用来做深度学习相关的计算。在 CV(计算机视觉),NLP(自然语言处理)的模型…...
详解MySql索引
目录 一 、概念 二、使用场景 三、索引使用 四、索引存在问题 五、命中索引问题 六、索引执行原理 一 、概念 索引是一种特殊的文件,包含着对数据表里所有记录的引用指针。暂时可以理解成C语言的指针,文章后面详解 二、使用场景 数据量较大,且…...
struct 和 union 的区别?
struct和union的分对应点总结 存储方式: struct:struct中的每个成员都拥有独立的内存空间。一个struct变量的总长度是其所有成员的长度之和,且通常会根据编译器的内存对齐规则进行适当调整。union:union中的所有成员共享同一段内…...
Linux - 安装 Jenkins(详细教程)
目录 前言一、简介二、安装前准备三、下载与安装四、配置镜像地址五、启动与关闭六、常用插件的安装 前言 虽然说网上有很多关于 Jenkins 安装的教程,但是大部分都不够详细,或者是需要搭配 docker 或者 k8s 等进行安装,对于新手小白而已&…...
【JAVA】JAVA方法的学习和创造
🌈个人主页: Aileen_0v0 🔥热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法|MySQL| 💫个人格言:“没有罗马,那就自己创造罗马~” 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不…...
Rust写一个wasm入门并在rspack和vite项目中使用(一)
rust打包wasm文档 文档地址 安装cargo-generate cargo install cargo-generate 安装过程中有问题的话手动安装cargo-generate下载地址 根据自己的系统下载压缩包,然后解压到用户/.cargo/bind目录下,将解压后的文件放到该目录下即可。 创建wasm项目 …...
HTTP和HTTPS的区别,HTTPS加密原理是?
HTTP和HTTPS都是网络传输协议,主要用于浏览器和服务器之间的数据传输,但它们在数据传输的安全性、加密方式、端口等方面有所不同。 数据传输的安全性:HTTP是明文传输,数据不加密,容易被黑客窃听、篡改或者伪造&#x…...
UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...
关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...
Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...
vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...
