NGINX 和 HAProxy:基于公有云标准环境的用户体验测试对比

news2024/11/15 7:28:50

原文作者:Amir Rawdat of F5

原文链接:NGINX 和 HAProxy:基于公有云标准环境的用户体验测试对比

转载来源:NGINX 官方网站

业内许多性能基准测试,都是基于峰值吞吐量或每秒请求数 (RPS),但这些指标可能会过分简化实际站点的性能情况。以峰值吞吐量或接近峰值吞吐量运行其服务的企业寥寥无几,因为无论采用哪种方式,10% 的性能变化都会产生重大影响。站点所需的吞吐量或 RPS 不是无限的,而是取决于外部因素,例如站点必须服务的并发用户数量和每个用户的活跃程度。最终重要的是您的用户能够获得最佳服务。最终用户并不在乎有多少人正在访问您的站点。他们只在意自己所获得的服务,而且他们无法接受因系统过载而导致的性能低下。

因此,对于企业真正重要的是,即使在高负载下也要能为所有用户提供持续的低延迟的可靠性能。在对比作为反向代理运行于 Amazon Elastic Compute Cloud (EC2) 之上的 NGINX 和 HAProxy 时,我们从以下两方面着手探讨:

  1. 测量这两种代理可以可靠处理的负载水平
  2. 计算延迟指标百分位数的分布情况,这是与用户体验最直接相关的指标

测试程序和收集的指标

我们使用压测工具 wrk2 模拟了一个客户端,在规定的时间段内发出连续的 HTTPS 请求。被测系统(HAProxy 或 NGINX)充当反向代理,与 wrk 线程模拟的客户端建立加密连接,将请求转发到运行 NGINX Plus R22 的后端 Web 服务器,Web 服务器将生成的响应(一个文件)返回给客户端。

这三个组件(客户端、反向代理和 Web 服务器)都在Ubuntu 20.04.1 LTS, EC2 的 c5n.2xlarge Amazon Machine Image (AMI) 实例上运行。

如上所述,我们从每次测试运行中收集了完整的延迟指标百分位分布。延迟指标是指客户端从生成请求到接收响应所用的时间。延迟百分位分布会将测试期间收集的延迟测量值从高到低(即从延迟时间最长到最短)进行排序。

测试方法

客户端

借助 wrk2(版本 4.0.0),我们在 Amazon EC2 实例上运行以下脚本:

关于此处的代码内容,请点击文章《NGINX 和 HAProxy:基于公有云标准环境的用户体验测试对比》进行查看。

为了模拟多个客户端访问 Web 应用,我们生成了 4 个 wrk 线程,这些线程共与反向代理建立 100 个连接。在 30 秒的测试运行期间,该脚本生成了指定数量的 RPS。这些参数对应于以下 wrk2 选项:

  • ‑t 选项 – 要创建的线程数 (4)
  • ‑c 选项 – 要创建的 TCP 连接数 (100)
  • ‑d 选项 – 测试期间的秒数(30 秒)
  • ‑R 选项 – 客户端发出的 RPS 数量
  • ‑‑latency 选项 – 输出结果包含校正的延迟百分位信息

我们在一组测试中逐渐增加了 RPS 的数量,直到其中一个代理的 CPU 利用率达到 100%。更多信息请参阅下文“性能测试结果”一节。

客户端和代理之间的所有连接均通过采用 TLSv1.3 的 HTTPS 建立。我们使用 256 位 ECC 密钥加密、PFS (Perfect Forward Secrecy,完全向前保密) 和 TLS_AES_256_GCM_SHA384 密码套件。(鉴于 TLSv1.2 仍被广泛使用,因此我们使用 TLSv1.2 重新运行了测试;结果与 TLSv1.3 非常相似,所以此处不再赘述。)

HAProxy:配置和版本控制

我们用 HAProxy 2.3 版(稳定版)进行反向代理性能测试。

热门网站的并发用户数量巨大。为了处理大规模流量,反向代理需要具有扩展能力以最大化利用多内核能力。现有两种基本的扩展方式:多进程和多线程。虽然 NGINX 和 HAProxy 都支持多进程,但二者之间有一个重要差别:在 HAProxy 的实现中,进程不共享内存(在 NGINX 中则得以共享)。HAProxy 无法跨进程共享状态将产生以下几个问题:

  • 必须为每个进程单独定义配置参数(包括限制、统计数据和速率)。
  • 性能指标将按进程收集;整合这些指标需要额外的配置,而相关配置可能会非常复杂。
  • 每个进程单独处理健康状况检查,因此目标服务器会被按进程(而非预想中的按服务器)进行探测。
  • 会话持久化无法实现。
  • 通过 HAProxy Runtime API 做出的动态配置更改只能应用于单个进程,因此必须为每个进程重复调用该 API。

由于上述问题,HAProxy 官方也强烈建议不要使用其多进程实现。下面引述摘自 HAProxy 配置手册:

使用多进程很难进行调试,强烈建议不要使用。

HAProxy 在 1.8 版中引入了多线程作为多进程的替代方案。多线程主要解决了状态共享问题,但正如我们在下文“性能测试结果”一节中所述,在多线程模式下的 HAProxy 的性能又不如多进程的模式下的性能。

我们的 HAProxy 配置包含了多线程模式 (HAProxy MT) 和多进程模式 (HAProxy MP) 的配置。为了在测试过程中在每个 RPS 级别上交替使用两种模式,针对相应的代码行,我们通过适当修改注释,以及重启 HAProxy 以使不同的配置生效:

关于此处的代码内容,请点击文章《NGINX 和 HAProxy:基于公有云标准环境的用户体验测试对比》进行查看。

以下是提供 HAProxy MT 的配置:在一个进程下创建了四个线程,并且每个线程绑定一个CPU核。HAProxy MP(下面注释的部分)中有四个进程,并且每个进程都固定在绑定到到一个 CPU 核上。

关于此处的代码内容,请点击文章《NGINX 和 HAProxy:基于公有云标准环境的用户体验测试对比》进行查看。

NGINX:配置和版本控制

我们用 NGINX 开源版 1.18.0 作为反向代理性能测试。

为了使用设备上所有可用的内核(本例中为四个),我们在 worker_processes 指令中添加了 auto 参数,这也是从我们的存储库分发的 nginx.conf 文件中的默认设置。此外,还添加了 worker_cpu_affinity 指令,以便将每个 worker 进程绑定到一个 CPU(第二个参数中的每个 1 表示设备中的一个 CPU)。

关于此处的代码内容,请点击文章《NGINX 和 HAProxy:基于公有云标准环境的用户体验测试对比》进行查看。

性能测试结果

由于反向代理充当应用的前端,因此其性能至关重要。

我们逐渐增加 RPS 的量级来测试每个反向代理(NGINX、HAProxy MP 和 HAProxy MT),直到其中一个的 CPU 利用率达到 100%。在 CPU 未耗尽的 RPS 能力上,这三个反向代理的性能不相上下。

HAProxy MT 的 CPU 利用率首先达到 100%(RPS 为 85,000),在达到该值后,HAProxy MT 和 HAProxy MP 的性能都急剧下降。下图展示了在该负载级别上每个反向代理的延迟百分位分布。该图使用 GitHub 上提供的 HdrHistogram 程序根据 wrk 脚本的输出结果绘制而成。

RPS 85,000级别上,在第 90 个百分位数上,HAProxy MT 的延迟指标骤升直,在逐渐提升到大约 1100 毫秒 (ms) 时逐渐趋于平稳。

较之 HAProxy MT,HAProxy MP 的性能更好 —— 其延迟在第 99 个百分位前一直以较慢的速度上升,之后在达到大约 400 毫秒时开始趋于平稳。(以上观察结果证明了 HAProxy MP 更为高效:HAProxy MT 在每个 RPS 级别上使用的 CPU 略多于 HAProxy MP。)

NGINX 在任何百分位上几乎都没有延迟。几乎所有用户访问可能出现的最高延迟(在第 99.9999 个百分位)大约为 8 毫秒。

关于用户体验,这些结果说明了什么呢?正如引言所述,从最终用户的角度来看,真正重要的指标是响应时间,而非被测系统的服务时间。

人们普遍存在一种误解,认为延迟分布中的中位数最能代表用户体验。事实上,中位数是大约一半的响应都要体验到的更高的延时!用户通常会在每次页面加载时发出许多请求并访问许多资源,因此他们的一些请求必然会在图表的上百分位(第 99 到第 99.9999 个百分位)处出现延迟。用户无法忍受性能低下,而高百分位的延时指标恰恰代表了多数请求都会经历的延时,因此更容易被他们注意到。

举个例子:您在杂货店结账的体验取决于从您排队结账的那一刻到离开商店所用的时间,而不仅仅是收银员进行商品扫码结算所花费的时间。例如,如果您前面的一位顾客对某件商品的价格提出质疑,而收银员必须找人进行核实,那么您的整体结账时间就会比平时长得多。

为了将这一点计入延迟结果,我们需要纠正所谓的 coordinated omission,其中(如 wrk2 README 文件末尾的注释中所述)“高延迟响应会触发负载生成器与服务器进行协调,从而避免在高延迟期间进行测量”。幸运的是,wrk2 默认纠正了 coordinated omission(有关 coordinated omission 的更多详细信息,请参阅 README 文件)。

当在 85,000 RPS 下 Haproxy MT 耗尽 CPU 时,许多请求都会出现高延迟。这些情况理应纳入数据,因为我们正在调整 coordinated omission。只要一两个高延迟请求便会延迟页面加载,让人感觉性能欠佳。假设一个真实系统一次为多位用户提供服务,即使只有 1% 的请求出现高延迟(第 99 个百分位的值),大部分用户都可能会受到影响。

结语

性能基准测试的要点之一是确定应用是否具有足够的响应能力来满足用户需求并留住用户。

NGINX 和 HAProxy 均基于纯软且采用事件驱动型架构。尽管 HAProxy MP 的性能优于 HAProxy MT,但由于无法在各个进程之间共享状态,因此管理变得更加复杂,详见上文 HAProxy一节。HAProxy MT 消除了这些局限性,但却降低了性能,如上述结果所示。

借助 NGINX,您则无需做出取舍 —— 因为进程之间共享状态,所以无需采用多线程模式。您可以获得多进程的卓越性能,而不会遇到 HAProxy 中的限制 —— 毕竟,这种限制是如此严重,以至于 HAProxy 直接建议不要使用其多进程实现。


更多资源

NGINX唯一中文官方社区 ,尽在 nginx.org.cn

更多 NGINX 相关的技术干货、互动问答、系列课程、活动资源:

开源社区官网:开源Web服务提供商 - NGINX开源社区
微信公众号:NGINX郑重宣布对开源社区的全新承诺

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

code of ridesharing

chengdu.node: num 经纬度 edge: num 两个节点之间的weight order: 编码了一下 label: 任意两点最短路长度 taxi.txt 司机个数 、capacity 、、变换的系数 司机所在位置、capacity order.txt num 订单提交到系统时间、起点node的id、…

过滤器与拦截器 - 登录校验与登录认证

文章目录 登录校验与登录认证一、登录认证1.1 基础登录功能1.2 会话技术1.2.1 介绍1.2.2 方案一 Cookie1.2.2.1 基本介绍1.2.2.2 服务端向浏览器响应Cookie1.2.2.3 浏览器向服务端请求携带Cookie 1.2.3 方案二 Session1.2.3.1 基本介绍1.2.3.2 服务端向浏览器响应Session1.2.3.…

如何把pdf拆分成一页一页?三个方法试试看

PDF文件作为常用的文件,其功能性较为全面。在日常工作过程中,PDF文件格式便于传输,且pdf文件不易被修改,能够增强文件的安全性和有效性。而在很多时候,为了能够快速地将PDF进行传输、保存等,需要对一些pdf文…

3D模型处理实战【Open3D】

在本文中,我们将学习如何使用 Python 的 Open3D 库探索、处理和可视化 3D 模型。 如果你正在考虑为特定任务处理 3D 数据/模型,例如为 3D 模型分类和/或分割训练 AI 模型,可能会发现本演练很有帮助。 在 Internet 上找到的 3D 模型&#xff…

Netty核心组件模块(二)

1.EventLoop组件 1.1.ChannelHandlerContext 1>.保存Channel相关的所有上下文信息,同时关联一个ChannelHandler对象; ChannelHandlerContext底层真实的类型为:DefaultChannelHandlerContext! 2>.即ChannelHandlerContext中包含一个具体的事件处理器ChannelHandler,同时…

GEE遥感云大数据林业应用典型案例实践及GPT模型应用

目录 一 平台及基础开发平台 二 GEE基础知识与ChatGPT等AI模型交互 三 重要知识点微型案例串讲与GPT模型交互演示 四 典型案例综合演练 更多推荐 聚焦目前遥感应用最热门领域之一的林业,重点结合典型应用案例综合展示GEE云平台的使用技巧和强大功能&#xff0c…

Spring Aop以及SpringBoot统一功能的处理

一.SpringAop 1.SpringAop是一种思想,指的是对使用比较多的功能进行统一处理,比如我们在写博客系统项目,当我们在登录博客列表页和博客详情页以及博客编辑页的时候的时候,都需要写代码进行登录验证,这时候代码就比较繁…

linux内核篇-内存管理(虚拟内存和物理内存、进程虚拟内存布局、内存映射)

主要包括虚拟内存和物理内存、进程内存空间、用户态和内核态的内存映射。 分段机制 分段机制比较符合逻辑,比如可以把程序分成代码段、全局变量段、堆栈段等。 分段的虚拟地址主要包含段选择因子和段内偏移。段选择子就保存在段寄存器中,段选择子中有…

【资料分享】低速数字输入电路

1、方案设计:单通道、单向、反相器 该电路采用单通道,单向光耦,只支持漏型输入,电路的输入端压差满足24V DC10%(21.6V DC-26.4V DC),输出端电压在0~3.3V范围摆动。 1.1关键技术规格 1.2具体原理图 1.3电路原理详解 …

数字图像处理-基础

数字图像处理-基础 文章目录 一、闲谈二、人类视觉系统三、光和电磁波谱四、图像感知与获取五、图像取样与量化5.1. 数字图像的表示5.2. 空间和灰度分辨率5.3. 图像内插5.3.1. 最近邻内插5.3.2. 双线性内插5.3.3. 双三次内插 六、像素间的关系6.1. 相邻像素6.2. 邻接性、连通性…

【架构设计】阿里开源架构Cola4.0的项目实践:订单系统

项目介绍 使用SpringBootMybaitsPlusCola(整洁面向对象分层架构)4.0重构订单功能 项目地址 Gitee:https://gitee.com/charles_ruan/smile-cola Github:https://github.com/charles0719/smile-cola 项目核心API 新增 POST http:…

华为OD机试真题 Java 实现【整理扑克牌】【2023Q1 100分】

一、题目描述 给定一组数字,表示扑克牌的牌面数字,忽略扑克牌的花色,请按如下规则对这一组扑克牌进行整理: 步骤1 对扑克牌进行分组,形成组合牌,规则如下: 当牌面数字相同张数大于等于4时&a…

【FPGA】Verilog:锁存器 Latch | RS Flip-Flop 与 D Flip-Flop 的实现

💭 写在前面:本章将理解 RS/D 锁存器的概念,了解 RS/D/JK 触发器的概念,使用 Verilog 实现各种锁存器 (Latch) 和翻转器 (Flip-Flop),并通过 FPGA 验证用 Verilog 的实现。 📜 本章目录: Ⅰ. …

Java中synchronized的优化

本文介绍为了实现高效并发,虚拟机对 synchronized 做的一系列的锁优化措施 高效并发是从 JDK5 升级到 JDK6 后一项重要的改进项,HotSpot 虚拟机开发团队在 JDK6 这个版本上花费了大量的资源去实现各种锁优化技术,如适应性自旋(Ada…

【fly-iot飞凡物联】(6):通过docker镜像使用gitbook启动ActorCloud项目文档,发现是个IOT功能非常丰富的项目,可以继续研究下去。

目录 前言1,关于 ActorCloud 使用手册2,使用docker 构建文档4,或者使用别人的gitbook镜像5,总结 前言 本文的原文连接是: https://blog.csdn.net/freewebsys/article/details/108971807 fly-iot飞凡物联专栏: https://…

含sop的配电网重构(含风光|可多时段拓展)

目录 1 主要内容 2 部分程序 3 下载链接 1 主要内容 之前分享了很多配电网重构的程序,每个程序针对场景限定性比较大,程序初学者修改起来难度较大,本次分享一个基础程序,针对含sop的配电网重构模型,含风电和光伏&…

skywalking安全认证问题

skywalking安全认证 一、问题二、步骤2.1 skywalking-aop配置文件修改2.2 agent配置文件修改 一、问题 在springboot项目使用java-agent接入skywalking时,为保证两者之间的数据安全传输,准备加个安全认证 参考文章: https://www.helloworld…

尝试探索水下目标检测,基于yolov5轻量级系列模型n/s/m开发构建海底生物检测系统

其实,水下目标检测相关的项目早在之前就已经做了几个了,但是没有系统性地对比过,感兴趣的话可以先看下之前的文章,如下: 《基于自建数据集【海底生物检测】使用YOLOv5-v6.1/2版本构建目标检测模型超详细教程》 《基于…

Qt编写视频监控系统73-不同视频流不同类型的判断和解析(http/m3u8/rtsp/rtmp等)

一、前言 这套视频监控系统大概从2018年起步整体框架,一步步积累到现在,中间经历了无数次的各种视频文件、视频流、视频设备的播放测试,比如光视频文件就有mp4/wmv/rmvb/mkv/avi等格式,视频设备有本地USB摄像头、桌面等&#xff…

【k8s】【ELK】【zookeeper+kafka+efak】日志环境部署

1、日志收集基本概念 k8s中pod的路径: containers log: /var/log/containers/*.log Pod log: /var/log/pods docker log: /var/lib/docker/containers/*/*.log如何收集日志 使用 EFKLogstashKafka 1、filebeat读取容器中的日志,然后写入K…