当前位置: 首页 > news >正文

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…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...

python打卡day49

知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...

python执行测试用例,allure报乱码且未成功生成报告

allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...

Reasoning over Uncertain Text by Generative Large Language Models

https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈

在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...

Java求职者面试指南:计算机基础与源码原理深度解析

Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...

MySQL JOIN 表过多的优化思路

当 MySQL 查询涉及大量表 JOIN 时,性能会显著下降。以下是优化思路和简易实现方法: 一、核心优化思路 减少 JOIN 数量 数据冗余:添加必要的冗余字段(如订单表直接存储用户名)合并表:将频繁关联的小表合并成…...