使用Nginx提升网站访问速度
2009-12-29 12:16:23 阿炯

本文主要介绍如何在 Linux 系统上安装高性能的 HTTP 服务器 -- Nginx、并在不改变原有网站结构的条件下用 Nginx 来提升网站的访问速度。

Nginx ("engine x") 是一个高性能的 HTTP 和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 代理服务器。是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的,它已经在该站点运行超过两年半了。Igor 将源代码以类 BSD 许可证的形式发布。Nginx 已经因为它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名了。

根据2008年6月的 NetCraft 调查报告显示,已经有超过两百万的主机使用了 Nginx,这个数字超过了另外一个轻量级的 HTTP 服务器 lighttpd,排名第四,并且发展迅速。下面是这份报告的前几名的报表:
产品     网站数
Apache     84,309,103
IIS     60,987,087
Google GFE     10,465,178
Unknown     4,903,174
nginx     2,125,160
Oversee     1,953,848
lighttpd     1,532,952

使用 Nginx 前必须了解的事项
1. 目前官方 Nginx 并不支持 Windows,您只能在包括 Linux、UNIX、BSD 系统下安装和使用;
2. Nginx 本身只是一个 HTTP 和反向代理服务器,它无法像 Apache 一样通过安装各种模块来支持不同的页面脚本,例如 PHP、CGI 等;
3. Nginx 支持简单的负载均衡和容错;
4. 支持作为基本 HTTP 服务器的功能,例如日志、压缩、Byte ranges、Chunked responses、SSL、虚拟主机等等,应有尽有。

安装Nginx
为了确保能在 Nginx 中使用正则表达式进行更灵活的配置,安装之前需要确定系统是否安装有 PCRE(Perl Compatible Regular Expressions)包。您可以到 ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/ 下载最新的 PCRE 源码包,使用下面命令下载编译和安装 PCRE 包:
# wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-7.7.tar.gz
# tar zxvf pcre-7.7.tar.gz
# cd pcre-7.7
# ./configure
# make
# make install

接下来安装 Nginx,Nginx 一般有两个版本,分别是稳定版和开发版,您可以根据您的目的来选择这两个版本的其中一个,下面是把 Nginx 安装到 /opt/nginx 目录下的详细步骤:

# wget http://sysoev.ru/nginx/nginx-0.6.31.tar.gz
# tar zxvf nginx-0.6.31.tar.gz
# cd nginx-0.6.31
# ./configure --with-http_stub_status_module –prefix=/opt/nginx
# make
# make install

其中参数 --with-http_stub_status_module 是为了启用 nginx 的 NginxStatus 功能,用来监控 Nginx 的当前状态。

安装成功后 /opt/nginx 目录下有四个子目录分别是:conf、html、logs、sbin 。其中 Nginx 的配置文件存放于 conf/nginx.conf,Nginx 只有一个程序文件位于 sbin 目录下的 nginx 文件。确保系统的 80 端口没被其他程序占用,运行 sbin/nginx 命令来启动 Nginx,打开浏览器访问此机器的 IP,如果浏览器出现 Welcome to nginx! 则表示 Nginx 已经安装并运行成功。

Nginx参数和控制

程序运行参数
Nginx 安装后只有一个程序文件,本身并不提供各种管理程序,它是使用参数和系统信号机制对 Nginx 进程本身进行控制的。 Nginx 的参数包括有如下几个:
-c :使用指定的配置文件而不是 conf 目录下的 nginx.conf 。

-t:测试配置文件是否正确,在运行时需要重新加载配置的时候,此命令非常重要,用来检测所修改的配置文 件是否有语法错误。

-v:显示 nginx 版本号。

-V:显示 nginx 的版本号以及编译环境信息以及编译时的参数。

例如我们要测试某个配置文件是否书写正确,我们可以使用以下命令:
sbin/nginx – t – c conf/nginx2.conf

通过信号对 Nginx 进行控制

Nginx 支持下表中的信号:
信号名     作用描述
TERM, INT     快速关闭程序,中止当前正在处理的请求
QUIT     处理完当前请求后,关闭程序
HUP     重新加载配置,并开启新的工作进程,关闭就的进程,此操作不会中断请求
USR1     重新打开日志文件,用于切换日志,例如每天生成一个新的日志文件
USR2     平滑升级可执行程序
WINCH     从容关闭工作进程

有两种方式来通过这些信号去控制 Nginx,第一是通过 logs 目录下的 nginx.pid 查看当前运行的 Nginx 的进程 ID,通过 kill – XXX 来控制 Nginx,其中 XXX 就是上表中列出的信号名。如果您的系统中只有一个 Nginx 进程,那您也可以通过 killall 命令来完成,例如运行 killall – s HUP nginx 来让 Nginx 重新加载配置。

配置Nginx
先来看一个实际的配置文件:
user  nobody;# 工作进程的属主
worker_processes  4;# 工作进程数,一般与 CPU 核数等同

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;

events {
use epoll;#Linux 下性能最好的 event 模式
worker_connections  2048;# 每个工作进程允许最大的同时连接数
}

http {
include       mime.types;
default_type  application/octet-stream;

#log_format  main  '$remote_addr - $remote_user [$time_local] $request '
#                  '"$status" $body_bytes_sent "$http_referer" '
#                  '"$http_user_agent" "$http_x_forwarded_for"';

#access_log  off;
access_log  logs/access.log;# 日志文件名

sendfile        on;
#tcp_nopush     on;
tcp_nodelay     on;

keepalive_timeout  65;

include gzip.conf;

# 集群中的所有后台服务器的配置信息
upstream tomcats {
server 192.168.0.11:8080 weight=10;
server 192.168.0.11:8081 weight=10;
server 192.168.0.12:8080 weight=10;
server 192.168.0.12:8081 weight=10;
server 192.168.0.13:8080 weight=10;
server 192.168.0.13:8081 weight=10;
}

server {
listen 80;#HTTP 的端口
server_name localhost;

charset utf-8;

#access_log  logs/host.access.log  main;

location ~ ^/NginxStatus/ {
stub_status on; #Nginx 状态监控配置
access_log off;
}

location ~ ^/(WEB-INF)/ {
deny all;
}

location ~ \.(htm|html|asp|php|gif|jpg|jpeg|png|bmp|ico|rar|css|js|
zip|java|jar|txt|flv|swf|mid|doc|ppt|xls|pdf|txt|mp3|wma)$ {
root /opt/webapp;
expires 24h;
}

location / {
proxy_pass http://tomcats;# 反向代理
include proxy.conf;
}

error_page 404 /html/404.html;

# redirect server error pages to the static page /50x.html
#
error_page 502 503 /html/502.html;
error_page 500 504 /50x.html;
location = /50x.html {
root   html;
}
}
}

Nginx监控
上面是一个实际网站的配置实例,其中灰色文字为配置说明。上述配置中,首先我们定义了一个 location ~ ^/NginxStatus/,这样通过 http://localhost/NginxStatus/ 就可以监控到 Nginx 的运行信息,显示的内容如下:
Active connections: 70
server accepts handled requests
14553819 14553819 19239266
Reading: 0 Writing: 3 Waiting: 67

NginxStatus 显示的内容意思如下:
* active connections – 当前 Nginx 正处理的活动连接数。
* server accepts handled requests -- 总共处理了 14553819 个连接 , 成功创建 14553819 次握手 ( 证明中间没有失败的 ), 总共处理了 19239266 个请求 ( 平均每次握手处理了 1.3 个数据请求 )。
* reading -- nginx 读取到客户端的 Header 信息数。
* writing -- nginx 返回给客户端的 Header 信息数。
* waiting -- 开启 keep-alive 的情况下,这个值等于 active - (reading + writing),意思就是 Nginx 已经处理完正在等候下一次请求指令的驻留连接。

静态文件处理

通过正则表达式,我们可让 Nginx 识别出各种静态文件,例如 images 路径下的所有请求可以写为:
location ~ ^/images/ {
root /opt/webapp/images;
}

而下面的配置则定义了几种文件类型的请求处理方式。

location ~ \.(htm|html|gif|jpg|jpeg|png|bmp|ico|css|js|txt)$ {
root /opt/webapp;
expires 24h;
}

对于例如图片、静态 HTML 文件、js 脚本文件和 css 样式文件等,我们希望 Nginx 直接处理并返回给浏览器,这样可以大大的加快网页浏览时的速度。因此对于这类文件我们需要通过 root 指令来指定文件的存放路径,同时因为这类文件并不常修改,通过 expires 指令来控制其在浏览器的缓存,以减少不必要的请求。 expires 指令可以控制 HTTP 应答中的“ Expires ”和“ Cache-Control ”的头标(起到控制页面缓存的作用)。您可以使用例如以下的格式来书写 Expires:
expires 1 January, 1970, 00:00:01 GMT;
expires 60s;
expires 30m;
expires 24h;
expires 1d;
expires max;
expires off;

动态页面请求处理
Nginx 本身并不支持现在流行的 JSP、ASP、PHP、PERL 等动态页面,但是它可以通过反向代理将请求发送到后端的服务器,例如 Tomcat、Apache、IIS 等来完成动态页面的请求处理。前面的配置示例中,我们首先定义了由 Nginx 直接处理的一些静态文件请求后,其他所有的请求通过 proxy_pass 指令传送给后端的服务器(在上述例子中是 Tomcat)。最简单的 proxy_pass 用法如下:
location / {
proxy_pass        http://localhost:8080;
proxy_set_header  X-Real-IP  $remote_addr;
}

这里我们没有使用到集群,而是将请求直接送到运行在 8080 端口的 Tomcat 服务上来完成类似 JSP 和 Servlet 的请求处理。

当页面的访问量非常大的时候,往往需要多个应用服务器来共同承担动态页面的执行操作,这时我们就需要使用集群的架构。Nginx 通过 upstream 指令来定义一个服务器的集群,最前面那个完整的例子中我们定义了一个名为 tomcats 的集群,这个集群中包括了三台服务器共 6 个 Tomcat 服务。而 proxy_pass 指令的写法变成了:
location / {
proxy_pass        http://tomcats;
proxy_set_header  X-Real-IP  $remote_addr;
}

在Nginx的集群配置中,Nginx 使用最简单的平均分配规则给集群中的每个节点分配请求。一旦某个节点失效时,或者重新起效时,Nginx 都会非常及时的处理状态的变化,以保证不会影响到用户的访问。


Nginx负载均衡参数说明

upstream的负载均衡,(以权重方式分发),weight是权重,可以根据机器配置定义权重。weigth参数表示权值,权值越高被分配到的比例越大。
upstream freeoapp {
server 192.168.80.121:80 weight=5;
server 192.168.80.122:80 weight=2;
server 192.168.80.123:80 weight=3;
}

以nginx热备方式分发,其它所有的非backup Server down或者忙的时候,请求backup机器。所以这台机器压力会最轻。
upstream freeoapp {
server 192.168.80.121:80;
server 192.168.80.122:80;
server 192.168.80.123:80 backup;
}

对 "/freeoa' 启用反向代理

location /freeoa {
proxy_pass http://127.0.0.1:88;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
#后端的Web服务器可以通过X-Forwarded-For获取用户真实IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#以下是一些反向代理的配置,可选。
proxy_set_header Host $host;
client_max_body_size 128m; #允许客户端请求的最大单文件字节数
client_body_buffer_size 128k; #缓冲区代理缓冲用户端请求的最大字节数,
proxy_connect_timeout 90; #nginx跟后端服务器连接超时时间(代理连接超时)
proxy_send_timeout 90; #后端服务器数据回传时间(代理发送超时)
proxy_read_timeout 90; #连接成功后,后端服务器响应时间(代理接收超时)
proxy_buffer_size 4k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小
proxy_buffers 4 32k; #proxy_buffers缓冲区,网页平均在32k以下的设置
proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2)
proxy_temp_file_write_size 64k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传
}

<proxy.conf>
proxy_connect_timeout 120;
proxy_read_timeout 240;
proxy_send_timeout 180;
proxy_buffering on;
proxy_buffer_size 128k;
proxy_buffers 32 32k;
proxy_busy_buffers_size 128k;
proxy_temp_file_write_size 128k;
proxy_next_upstream error timeout http_404;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_intercept_errors on;
proxy_ignore_client_abort on;

Nginx中upstream有以下几种方式:

1、轮询(weight=1)
默认选项,当weight不指定时,各服务器weight相同, 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除(最好带上keepalive 30;参数,即30秒节点没响应即可移除)。
upstream bakend {
server 192.168.10.10;
server 192.168.10.11;
keepalive 30;
}

2、weight
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。如果后端服务器down掉,能自动剔除。比如下面配置,则10.11服务器的访问量为10.10服务器的两倍。
upstream bakend {
server 192.168.10.10 weight=1;
server 192.168.10.11 weight=2;
}

3、ip_hash
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session不能跨服务器的问题。如果后端服务器down掉,要手工停掉。
upstream resinserver{
ip_hash;
server 192.168.10.10:8080;
server 192.168.10.11:8080;
}

4、fair(第三方插件)
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
upstream resinserver{
server 192.168.1.10:8080;
server 192.168.1.11:8080;
fair;
}

5、url_hash(第三方插件)
按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存服务器时比较有效。在upstream中加入hash语句,hash_method是使用的hash算法。
upstream resinserver{
server 192.168.1.10:8080;
server 192.168.1.11:8080;
hash $request_uri;
hash_method crc32;
}

设备的状态有:
1.down 表示当前的server暂时不参与负载
2.weight 权重,默认为1;weight越大,负载的权重就越大。
3.max_fails 允许请求失败的次数默认为1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误。
4.fail_timeout max_fails次失败后,暂停的时间。
5.backup 备用服务器, 其它所有的非backup机器down或者忙的时候,请求backup机器,所以这台机器压力会最轻。

nginx支持同时设置多组的负载均衡,用来给不用的server来使用。
client_body_in_file_only 设置为On时可以将client post过来的数据记录到文件中用来做debug
client_body_temp_path 设置记录文件的目录,可以设置最多3层目录
location 对url进行匹配,可以进行重定向或者进行新的代理 负载均衡


总结
尽管整个程序包只有五百多K,但麻雀虽小、五脏俱全。Nginx 官方提供的各种功能模块应有尽有,结合这些模块可以完整各种各样的配置要求,例如:压缩、防盗链、集群、FastCGI、流媒体服务器、 Memcached 支持、URL 重写等等,更关键的是 Nginx 拥有 Apache 和其他 HTTP 服务器无法比拟的高性能。甚至可以在不改变原有网站的架构上,通过在前端引入 Nginx 来提升网站的访问速度。


Netcraft 2019 年 4 月 Web 服务器排名 Nginx 首度登上第一宝座

Netcraft 发布了 2019 年 4 月 Web 服务器调查报告,排名前三的是 nginx、Apache 和 Microsoft Server。这是 nginx 首度登上第一宝座,其原因来自于微软和 Apache 市场份额的减少。四月份比三月的统计少掉了一些网站,而这些网站大部分来自于微软和 Apache,这两家供应商的的市场份额分别下降了 1.01 和 0.87 个百分点。

Netcraft 表示,这些变化让 nginx 成为网站数量的领先者。同时,这也是自 1996 年以来,除了微软与 Apache,首次有另一家供应商网站的市场份额达到了第一的位置。

Apache 从 1996 年一直都是 Web 服务器中的市场份额王者,它称霸了 18 年,近几年来这个情况才有了一些变化。在 2014 年,Apache 首次被微软挤下第一名的宝座,虽然在 2016 年初重回第一,但在本月再次被 nginx 超越。不过,Apache 在其他指标的表现仍然活跃,以活跃站点数量来看,占 30.30% 的 Apache 远超过了 nginx 的 20.73%。虽然差距仍然相当大,但有持续拉近的趋势。在前百万站点中,Apache 的市场份额将近三分之一,而 nginx 占 26.22%。

对此 Netcraft 表示,nginx 成长力道强劲,在几年内就会挑战到 Apache 在整个互联网的地位。


所有站点的市场份额


活跃站点的市场份额


前百万站点的市场份额


计算机的市场份额


域名的市场份额

了解更多数据可查阅榜单详情

Netcraft 公司官网每月公布的调研数据(Web Server Survey)已成为当今人们了解全球网站数量以及服务器市场分额情况的主要参考依据,时常被诸如华尔街杂志,英国 BBC,Slashdot 等媒体报道或引用。


Nginx 版本控制

Nginx 版本控制介绍

Nginx 在 Nginx Open Source 代码存储库中维护着两个分支,分别为主线版和稳定版:
1).主线版是更新活跃的开发分支,会添加最新功能和错误修复。其版本号的第二位用奇数表示,例如1.19.0。
2).稳定版接收针对高严重性错误的修复,但不会加入新功能。其版本号的第二位用偶数表示,例如 1.18.0。

“稳定”意味着什么?
就 Nginx Open Source 而言,“稳定”一词是指功能和更新频率稳定,与软件质量无关。稳定分支在其生命周期中不接收任何新功能,通常仅接收一两个更新用于修复严重的错误。稳定分支的生命周期为一年。每年四月,我们就会停止对当前稳定分支的维护,不再提供任何错误修复。这会触发两个事件:
1).对当前主线分支进行复刻 (Fork),以创建下一个稳定分支。新的稳定分支会继承主线分支在过去一年中进行的所有错误修复、功能更新和其他更改。上个月,就是通过对 Nginx 1.17.10 进行复刻,创建了 Nginx 1.18.0。请注意,在发布新的主线分支之前,“稳定分支”与当前主线分支完全相同,并且可能包含近几天内新增的功能(Nginx 1.18 分支从今天起终止此状态)。

2).主线分支会获得版本升级;也就是说,其版本号的第二位会增加为下一个奇数。我们会持续对主线分支进行开发,每四到六周就会基于主线分支创建一个新版本。今天发布的 Nginx 1.19.0 是基于 Nginx 1.19 主线分支创建的首个版本。


Nginx Open Source 分支的 2020 年度版本升级

Nginx Plus 使用哪个分支?
作为 Nginx 的商业版本,Nginx Plus在单独的专用代码存储库中进行维护。它始终基于 Nginx 主线分支的最新版本,并整合了 Nginx Plus 中的其他专有功能。在撰写本文时,最新版本是基于 Nginx 1.17.10 的Nginx Plus R21。

我应该使用哪个分支?
我们通常建议使用主线分支。它包含了我们添加的所有新功能、性能改进和增强功能。我们会积极对主线分支进行测试和质量检查,并且作为 Nginx Plus 构建的来源,它完全适合生产使用。如果担心因监控主线分支新功能和错误修复而产生额外开销,那就使用稳定分支,这样您只需每年检查一次新功能,并且不需要经常进行错误修复。

Nginx 1.17 回顾,即 Nginx 1.18 稳定分支中的新增功能
Nginx 1.17 开发周期引入了一些新功能和增强功能,包括分别对 ngx_http_limit_req_module 和 ngx_http_limit_conn_module 中的请求速率和连接限制进行了增强,为 ngx_http_core_module 添加了身份验证‑延迟指令,为捕捉代理协议服务器地址和端口的 grpc_pass 指令和变量引入变量支持等。在更详细地介绍最重要的增强功能之前,我们先了解下 Nginx 1.17 进行的更新:10 个主线版、37 个错误修复、11 项新功能

对 HTTP 请求速率和连接限制进行了增强
limit_rate和 limit_rate_after 指令控制 Nginx 响应请求所需的带宽(每秒字节数)。在 Nginx 1.17.0 和更高版本中,设置该速率的参数可以是一个变量,该变量可以基于请求的属性进行动态控制。有关示例,请参阅动态带宽控制。

Nginx 1.17.1 通过 limit_req_dry_run 指令添加空运行模式以执行请求速率限制。 在空运行模式下,Nginx Plus 不会强制执行速率限制,但仍会跟踪共享内存区域中过多请求的速率,并将每个超出配置限制的请求写入错误日志。这有助于您更轻松地确定哪个速率限制适合您站点的流量模式。有关更多详细信息,请参见空运行模式下的速率限制测试。

为了提高空运行模式的有效性,Nginx 1.17.6 添加了 $limit_req_status 变量,该变量可以包含在访问日志条目中,以捕获速率限制对请求处理的影响,即确定请求处于以下哪种状态:
已通过(已立即转发到后端服务器) [PASSED]
被延迟 [DELAYED]
被拒绝 [REJECTED]
在空运行模式下被视为被延迟 [DELAYED_DRY_RUN]
在空运行模式下被计为被拒绝 [REJECTED_DRY_RUN]

Nginx 1.17.6 还通过 limit_conn_dry_run 指令添加空运行模式以进行连接限制,并通过和 $limit_conn_status 变量捕捉连接请求处于以下哪种状态:
已通过(已转发到后端服务器) [PASSED]
被拒绝 [REJECTED]
在空运行模式下被视为被拒绝 [REJECTED_DRY_RUN]

有关示例配置,请参阅对连接限制的增强。

新 auth_delay 指令
auth_delay指令(添加在 Nginx 1.17.10 中)支持对未授权请求进行延迟处理,并将状态代码 401(未授权)返回客户端。这可以在处理访问请求时防御定时攻击。可用的身份验证方法包括:
密码(当使用 ngx_http_auth_basic_module 时)
子请求的结果(在 ngx_http_auth_request_module 中提供)
出示 JWT(在 ngx_http_auth_jwt_module 中提供)

对 grpc_pass 指令的变量支持
Nginx 1.13.10 中增加了对 gRPC 流量的原生支持,包括 grpc_pass 指令,该指令指定了 Nginx 将 gRPC 请求传递到哪台服务器。 在 Nginx 1.17.8 中,我们添加了在服务器标识符中加入域名的功能,以支持在上游服务器组中进行搜索。如果找不到域名,Nginx 会转而使用解析器来识别服务器地址。

其他 PROXY 协议变量
PROXY 协议支持第 4 层代理将原始客户端信息提供给处理请求的下一个代理或负载均衡器。这对于需要了解客户端 IP 地址的用例来说非常重要,例如限制每个客户端的连接数(使用 least_conn 指令)。该数据在 $proxy_protocol_addr 变量 (HTTP | Stream) 中提供。

当部署多个4 层代理时,Nginx 需要知道客户端最初所连接的代理服务器的 IP 地址和端口。PROXY 协议元数据包含此信息,Nginx 1.17.6 向 HTTP 和 Stream 模块添加以下变量以捕获该信息:
$proxy_protocol_server_addr  (HTTP | Stream)
$proxy_protocol_server_port  (HTTP | Stream)

注意:只有当您还为 listen 指令添加了 proxy_protocol参数,以支持代理协议处理时,这些变量才会被填充。

将变量支持添加到了 proxy_upload_rate 和proxy_download_rate 指令中
Stream 模块中的 proxy_upload_rate 和 proxy_download_rate指令分别控制 Nginx 从客户端或代理服务器读取数据速率。在 Nginx 1.17.0 和更高版本中,这些指令会接受一个可变参数,以支持您定义条件特定的速率。

添加了对 ioctl(FIONREAD) 系统调用的支持
在 Linux 系统中,ioctl() 系统调用提供了可从主机设备读取的字节数。Nginx 1.17.5 添加了 ioctl(FIONREAD),以防止当将数据添加到套接字缓冲区的速度超过 Nginx 的读取和处理速度时,发生循环。当内核不提供可用字节数时,我们可以使用 ioctl(FIONREAD) 从填充缓冲区中获取此信息。

在 Perl internal_redirect 函数中指定已命名位置
在 Nginx 1.17.2 和更高版本中,Nginx Perl module 中 internal_redirect 函数的 uri 参数可以是转义 URI 或已命名位置。

Nginx 1.19 有哪些特性?
Nginx 1.19.0 包含对 QUIC (HTTP/3) 的支持,这是对客户端和网站、应用和 API 之间通信传输协议的下一个重要更新。


Cloudflare内部使用Rust编写的Pingora来代替Nginx

长期以来,Cloudflare 一直依赖 Nginx 作为其 HTTP 代理堆栈的一部分;但在2022年9月其宣布已将 Nginx 替换为其内部由 Rust 编写的 Pingora 软件,称已经建立了一个更快、更高效、更通用的内部代理,作为我们当前和未来产品的平台。据介绍,该软件每天可处理超过一万亿个请求,并可在只使用原本约三分之一的 CPU 和内存资源的情况下提供更好的性能。

随着 Cloudflare 规模的扩大,我们已经超越了 NGINX。多年来它一直很棒,但随着时间的推移,它在我们规模上的局限性意味着构建新的东西是有意义的。无法再获得我们需要的性能,NGINX 也没有我们非常复杂的环境所需的功能。

Cloudflare 现在主要专注于在其网络和互联网上的服务器之间代理流量的服务,Pingora 代理服务则为其 CDN、Workers fetch、Tunnel、Stream、R2 和许多其他功能和产品提供了动力。Cloudflare 称其选择建立另一个新代理的原因在于,多年来在 NGINX 的使用上遇到了很多限制。其中包括会损害性能的架构限制,以及某些类型的功能难以添加等。并指出,NGINX 社区也不是很活跃,开发往往是 “闭门造车”。而他们选择 Rust 作为项目的语言,是因为它可以在不影响性能的情况下以内存安全的方式完成 C 可以做的事情。Cloudflare 还为 Rust 实现了自己的 HTTP 库,以满足他们所有不同的需求。Pingora 采用多线程架构而不是多进程。

Pingora 上的总体流量显示,TTFB 中位数减少了 5 毫秒,第 95 个百分位数减少了 80 毫秒。在所有 customers 中,与 old service 相比,Pingora 每秒的新连接数只有三分之一。对于一个 major customer 来说,它将连接重用率从 87.1% 提高到 99.92%,这使得新连接到其 origins 的次数减少了 160 倍。“为了更直观地呈现这一数字,通过切换到 Pingora,我们每天为客户和用户节省了 434 年的 handshake time。”

在生产环境中,与 old service 相比,Pingora 在相同流量负载的情况下消耗的 CPU 和内存减少了约 70% 和 67%。而除了性能优势之外,Pingora 还被认为更安全,这在很大程度上则要归功于 Rust 的使用。不过 Pingora 尚未开源,Cloudflare 表示他们正在制定计划,但目前该 HTTP 代理尚未公开。



该文章最后由 阿炯 于 2022-09-17 08:11:59 更新,目前是第 2 版。