「网络架构」网络代理第二部分:Nginx作为转发HTTP代理

简介: 「网络架构」网络代理第二部分:Nginx作为转发HTTP代理

我刚开始使用OpenDNS时,我的首要任务是弄清楚Nginx的工作方式,并为其编写一个自定义C模块来处理一些业务逻辑。 Nginx将反向代理到Apache Traffic Server(ATS),它将执行实际的正向代理。 这是一个简化图:


事实证明,Nginx易于理解和使用。这与ATS相反,后者更大,更复杂,而且简直不好玩。结果,“为什么我们不整个使用Nginx?”成为一个流行的问题,尤其是在确定代理将不进行任何缓存之后。

正向代理尽管Nginx是旨在与明确定义的上游一起使用的反向代理:

http { upstream myapp1 { server srv1.example.com; server srv2.example.com; server srv3.example.com; }

server { listen 80; location / { proxy_pass http://myapp1; } }}

也可以将其配置为基于某些变量使用上游,例如Host标头:

http { server { listen 80; location / { proxy_pass http://$http_host$request_uri; } }}

这实际上工作得很好。主要警告是Host标头可以匹配配置中的预定义上游{}(如果存在):

http { ... upstream foo { server bar; } ... server { listen 80; location / { proxy_pass http://$http_host$request_uri; } }}

然后,这样的请求将匹配foo并被代理到bar:

GET / HTTP/1.1Accept: */*Host: foo

可以通过在自定义模块中使用新变量来扩展此方法,而不是使用内置的$ http_host和$ request_uri进行更好的目标控制,错误处理等。

一切工作都非常好-请注意,这是一个HTTP(端口80)代理,在此我们不考虑HTTPS情况。一方面,Nginx无法识别显式HTTPS代理中使用的CONNECT方法,因此将永远无法工作。正如我在之前的博客文章中提到的那样,我们的智能代理通常采用一种更加非常规的方法。

一个大问题是性能。我们使用ATS进行的初始负载测试得出的数据少于理想值。Nginx的“ hack”对其性能有没有影响?

负载测试


跳过更详细的信息,我们的设置使用wrk作为负载生成器,并使用自定义C程序作为上游。定制上游是非常基本的。它所做的就是接受连接,并通过静态二进制Blob响应任何看起来像HTTP的请求。永远不会显式关闭连接,以消除不必要的额外TCP会话导致的结果中的任何潜在偏差。

我们首先通过直接加载上游服务器来建立基准:

Running 30s test 10 threads and 100 connections Thread Stats Avg Stdev Max +/- Stdev Latency 3.27ms 680.48us 5.04ms 71.95% Req/Sec 3.21k 350.69 4.33k 69.67% 911723 requests in 30.00s, 3.19GB read 100 total connects (of which 0 were reconnects)Requests/sec: 30393.62Transfer/sec: 108.78MB

一切看起来都不错,wrk按预期创建了100个连接,并设法每秒挤出3万个请求。

现在,让我们通过Nginx转发代理(2个工作组)进行重复:

Running 30s test 10 threads and 100 connections Thread Stats Avg Stdev Max +/- Stdev Latency 6.42ms 14.37ms 211.84ms 99.50% Req/Sec 1.91k 245.53 2.63k 83.75% 552173 requests in 30.00s, 1.95GB read 5570 total connects (of which 5470 were reconnects)Requests/sec: 18406.39Transfer/sec: 66.53MB

这几乎使可能的吞吐量减半。

通过手动请求,我们发现通过Nginx并不会真正增加任何明显的延迟。Nginx工作人员在测试期间获得了接近100%的CPU使用率,但是增加工作人员人数并没有多大帮助。

上游情况如何,在两种情况下会看到什么?

快速更新以打印一些统计信息后,在直接情况下一切看起来都很好-wrk和上游服务器报告的数字符合预期。但是,在查看上游服务器统计信息时,我们在代理情况下发现了一些令人吃惊的事情:

status: 552263 connects, 552263 closes, 30926728 bytes, 552263 packets

看起来Nginx为往上游的每个请求创建了一个新连接,尽管wrk仅向下游进行了100个连接…

深入Nginx核心并更全面地阅读文档,事情开始变得有意义。Nginx是一个负载均衡器,其中“负载”等于请求,而不是连接。连接可以发出任意数量的请求,重要的是在后端之间平均分配这些请求。就目前而言,Nginx在每个请求之后关闭上游连接。上游keepalive模块尝试通过始终保持一定数量的持久连接保持打开状态来对此进行轻微补救。Nginx Plus提供了诸如会话持久性(Session Persistence)之类的额外功能(顺便说一句,还存在一个等效的开源模块)—使请求可以更一致地路由到相同的上游。

我们真正想要的是客户端及其各自上游之间的一对一持久连接映射。在我们的案例中,上游是完全任意的,我们要避免创建不必要的连接,更重要的是,不要以任何方式“共享”上游连接。我们的会议是整个客户连接本身。

补丁

该解决方案非常简单,我们已经在Github 上提供了该解决方案。

通过此更改重新运行负载测试,我们可以获得更好的结果,概述了保持TCP连接持久性并避免那些昂贵的打开/关闭操作的重要性:

Running 30s test 10 threads and 100 connections Thread Stats Avg Stdev Max +/- Stdev Latency 10.82ms 48.67ms 332.65ms 97.72% Req/Sec 3.00k 505.22 4.46k 95.81% 854946 requests in 30.00s, 3.02GB read 8600 total connects (of which 8500 were reconnects)Requests/sec: 28498.99Transfer/sec: 103.01MB

上游的数字与wrk的数字匹配:

status: 8600 connects, 8600 closes, 47882016 bytes, 855036 packets

但是,仍然存在问题。有8600个连接,而不仅仅是100个。Nginx决定关闭上游和下游的许多连接。当进行调试以查看原因时,我们最终追溯到“ lingering_close_handler”:

...nginx: _ngx_http_close_request(r=0000000000C260D0) from ngx_http_lingering_close_handler, L: 3218nginx: ngx_http_close_connection(00007FD41B057A48) from _ngx_http_close_request, L: 3358...

由于即使使用此行为,整体效果还是令人满意的,因此我暂时不这样做了。

收盘中

我们已经将Nginx作为生产中的正向HTTP代理运行了一段时间,几乎没有问题。我们希望继续扩展Nginx的功能,并推动新的界限。请留意未来的博客文章和代码片段/补丁。

*这是一个重写的补丁程序(原始补丁有点笨拙),这个新代码最近才投入生产。如果有任何问题,我将进行任何调整以更新公共补丁。

相关文章
|
3月前
|
安全 应用服务中间件 Linux
Debian操作系统如何安装Nginx并开启HTTP2
本指南介绍了在Linux系统中通过源码编译安装Nginx的完整流程。首先更新软件包列表并安装必要的编译依赖,接着下载指定版本的Nginx源码包(如1.24.0),检查文件完整性后解压。随后通过配置脚本指定安装路径与模块(如HTTP SSL模块),执行编译和安装命令。最后创建软链接以便全局调用,并提供启动、停止及重载Nginx的命令,同时提醒注意安全组设置以确保正常访问。
|
6月前
|
数据可视化 关系型数据库 MySQL
ELK实现nginx、mysql、http的日志可视化实验
通过本文的步骤,你可以成功配置ELK(Elasticsearch, Logstash, Kibana)来实现nginx、mysql和http日志的可视化。通过Kibana,你可以直观地查看和分析日志数据,从而更好地监控和管理系统。希望这些步骤能帮助你在实际项目中有效地利用ELK来处理日志数据。
466 90
|
9月前
|
负载均衡 网络协议 网络性能优化
动态IP代理技术详解及网络性能优化
动态IP代理技术通过灵活更换IP地址,广泛应用于数据采集、网络安全测试等领域。本文详细解析其工作原理,涵盖HTTP、SOCKS代理及代理池的实现方法,并提供代码示例。同时探讨配置动态代理IP后如何通过智能调度、负载均衡、优化协议选择等方式提升网络性能,确保高效稳定的网络访问。
899 2
|
5月前
|
人工智能 供应链 调度
|
8月前
|
网络协议 应用服务中间件 网络安全
Nginx,正向代理
本文介绍了Nginx作为HTTPS正向代理的两种方案:HTTP CONNECT隧道(7层)和NGINX stream(4层)。HTTP CONNECT隧道需要客户端手动配置代理,通过CONNECT请求建立隧道;而NGINX stream则更适合透明代理,利用SNI字段实现流量转发。文章详细讲解了两者的原理、环境搭建、使用场景及常见问题,并提供了配置示例和最佳实践建议。内容转载自阿里云开发者社区@怀知的文章,推荐读者参阅原文获取更多信息。感谢您的阅读!
947 80
Nginx,正向代理
|
4月前
|
数据采集 监控 安全
HTTP代理和IP代理的不同点及代理IP能带来的好处分析
总的来说,无论是HTTP代理还是IP代理,选择哪一种主要还是要看你的需求和使用场景,同时也要为可能的风险做好准备。
118 9
|
4月前
|
安全 网络协议 算法
HTTP/HTTPS与SOCKS5协议在隧道代理中的兼容性设计解析
本文系统探讨了构建企业级双协议隧道代理系统的挑战与实现。首先对比HTTP/HTTPS和SOCKS5协议特性,分析其在工作模型、连接管理和加密方式上的差异。接着提出兼容性架构设计,包括双协议接入层与统一隧道内核,通过协议识别模块和分层设计实现高效转换。关键技术部分深入解析协议转换引擎、连接管理策略及加密传输方案,并从性能优化、安全增强到典型应用场景全面展开。最后指出未来发展趋势将更高效、安全与智能。
153 1
|
5月前
|
人工智能 搜索推荐 开发者
GPT-4o测评准确率竟不到1%!BrowseComp:OpenAI开源AI代理评测新基准,1266道高难度网络检索问题
OpenAI最新开源的BrowseComp基准包含1266个高难度网络检索问题,覆盖影视、科技、艺术等九大领域,其最新Deep Research模型以51.5%准确率展现复杂信息整合能力,为AI代理的浏览能力评估建立新标准。
265 4
GPT-4o测评准确率竟不到1%!BrowseComp:OpenAI开源AI代理评测新基准,1266道高难度网络检索问题
|
6月前
|
机器学习/深度学习 存储 人工智能
SAFEARENA: 评估自主网络代理的安全性
基于大语言模型的智能体在解决基于网络的任务方面正变得越来越熟练。随着这一能力的增强,也随之带来了更大的被恶意利用的风险,例如在在线论坛上发布虚假信息,或在网站上销售非法物质。为了评估这些风险,我们提出了SAFEARENA,这是第一个专注于故意滥用网络代理的基准测试。SAFEARENA包含四个网站上共计500个任务,其中250个是安全的,250个是有害的。我们将有害任务分为五类:虚假信息、非法活动、骚扰、网络犯罪和社会偏见,旨在评估网络代理的真实滥用情况。我们对包括GPT-4o、Claude-3.5 Sonnet、Qwen-2-VL 72B和Llama-3.2 90B在内的领先基于大语言模型的网
252 11
SAFEARENA: 评估自主网络代理的安全性
|
7月前
|
机器学习/深度学习 算法 文件存储
YOLOv11改进策略【模型轻量化】| MoblieNetV3:基于搜索技术和新颖架构设计的轻量型网络模型
YOLOv11改进策略【模型轻量化】| MoblieNetV3:基于搜索技术和新颖架构设计的轻量型网络模型
506 10
YOLOv11改进策略【模型轻量化】| MoblieNetV3:基于搜索技术和新颖架构设计的轻量型网络模型

热门文章

最新文章