9.静态内容服务器
配置 NGINX 以提供静态内容,具有特定于类型的根目录、检查文件是否存在和性能优化。
根目录和索引文件(Root Directory and Index Files)
根指令指定将用于搜索文件的根(root)目录。为了获取请求文件的路径,NGINX将请求URI附加到 root指令指定的路径中。该指令可以放置在 http {} server {}和 location {}上下文中的任何级别。在下面的示例中,root该指令是为虚拟服务器定义的。它适用于不包含 root该指令以显式重定义根的所有 location {}块:
server {
root /www/data;
location / {
}
location /images/ {
}
location ~ \.(mp3|mp4) {
root /www/media;
}
}
在这里,NGINX搜索在文件系统目录 /www/data/images/中以 /images/开头的URI。但是,如果 URI 以 .mp3 or .mp4扩展名结尾,NGINX 会改为在目录 /www/media/中搜索 该文件,因为它是在 location匹配块中定义的。
如果请求以斜杠结尾,NGINX 会将其视为对目录的请求,并尝试在目录中查找索引文件。index 指令定义索引文件的名称(默认值为 index.html)。继续该示例,如果请求 URI 为 /images/some/path/,NGINX 会传递文件 /www/data/images/some/path/index.html(如果存在)。如果没有,NGINX默认返回HTTP代码 404(未找到)。要将 NGINX 配置为返回自动生成的目录列表,请将 on参数包含在自动索引(autoindex)指令中:
location /images/ {
autoindex on;
}
您可以在 index指令中列出多个文件名。NGINX按指定的顺序搜索文件,并返回找到的第一个文件。
location / {
index index.$geo.html index.htm index.html;
}
此处使用的变量是通过 geo 指令设置的自定义变量。$geo变量的值取决于客户端的 IP 地址。
为了返回索引文件,NGINX检查其是否存在,然后通过将索引文件的名称附加到基本URI来对获得的URI进行内部重定向。内部重定向会导致对某个位置的新搜索,并可能最终出现在另一个位置,如以下示例所示:
location / {
root /data;
index index.html index.php;
}
location ~ \.php {
fastcgi_pass localhost:8000;
#...
}
在这里,如果请求中的 URI 是 /path/ ,并且 /data/path/index.html不存在但 /data/path/index.php确实存在,则内部重定向将 /path/index.php映射到第二个位置。因此,请求被代理了。
尝试多个选项(Trying Several Options)
try_files指令可用于检查指定的文件或目录是否存在;NGINX会进行内部重定向,如果没有,则会返回指定的状态代码。例如,要检查与请求 URI 对应的文件是否存在,请使用 try_files指令和 $uri变量,如下所示:
server {
root /www/data;
location /images/ {
try_files $uri /images/default.gif;
}
}
该文件以 URI 的形式指定,该 URI 使用在当前位置或虚拟服务器的上下文中设置的 root 或 alias 指令进行处理。在这种情况下,如果与原始 URI 对应的文件不存在,NGINX 会进行内部重定向到最后一个参数指定的 URI,返回 /www/data/images/default.gif 。
最后一个参数也可以是状态代码(前面直接带有等号)或位置名称。在下面的示例中,如果 try_files指令的所有参数都没有解析为现有文件或目录,则会返回 404错误。
location / {
try_files $uri $uri/ $uri.html =404;
}
在下一个示例中,如果原始 URI 和带有附加尾部斜杠的 URI 均未解析为现有文件或目录,则请求将重定向到命名位置,该位置将其传递到代理服务器。
location / {
try_files $uri $uri/ @backend;
}
location @backend {
proxy_pass http://backend.example.com;
}
优化内容服务的性能(Optimizing Performance for Serving Content)
加载速度是提供任何内容的关键因素。对NGINX配置进行微小的优化可能会提高生产力并有助于达到最佳性能。
1.启用 sendfile (Enabling sendfile)
默认情况下,NGINX处理文件传输本身,并在发送之前将文件复制到缓 冲区中。启用 sendfile 指令可消除将数据复制到缓冲区的步骤,并允许将数据从一个文件描述符直接复制到另一个文件描述符。或者,为了防止一个快速连接完全占用工作进程,可以使用 sendfile_max_chunk 指令来限制在单个 sendfile()调用中传输的数据量(在此示例中为 1 MB):
location /mp3 {
sendfile on;
sendfile_max_chunk 1m;
#...
}
2.启用 tcp_nopush (Enabling tcp_nopush)
将 tcp_nopush 指令与 sendfile on;指令一起使用。这使得NGINX能够在 sendfile()获得数据块后立即在一个数据包中发送HTTP响应标头。
location /mp3 {
sendfile on;
tcp_nopush on;
#...
}
3.启用 tcp_nodelay (Enabling tcp_nodelay)
tcp_nodelay指令允许覆盖Nagle算法,该算法最初旨在解决慢速网络中小数据包的问题。该算法将许多小数据包合并为一个较大的数据包,并以 200毫秒延迟发送数据包。如 今,在提供大型静态文件时,无论数据包大小如何,都可以立即发送数据。延迟也会影响在线应用程序(ssh、在线游戏、在线交易等)。默认情况下,tcp_nodelay 指令设置为 on这意味着 Nagle 算法被禁用。仅将此指令用于保持连接连接:
location /mp3 {
tcp_nodelay on;
keepalive_timeout 65;
#...
}
4.优化积压工作队列(Optimizing the Backlog Queue)
其中一个重要因素是NGINX处理传入连接的速度。一般规则是建立连接后,将其放入侦听套接字的“侦听”队列中。在正常负载下,队列要么很小,要么根本没有队列。但在高负载下,队列可能会急剧增长,从而导致性能不均衡、连接断开和延迟增加。
显示侦听队列(Displaying the Listen Queue)
要显示当前侦听队列,请运行以下命令:
netstat -Lan
输出可能如下所示,它表明在端口 80 上的侦听队列中有 10个未接受的连接,而配置的最大连接数为 128个。 这种情况很正常。
Current listen queue sizes (qlen/incqlen/maxqlen)
Listen Local Address
0/0/128 *.12345
10/0/128 *.80
0/0/128 *.8080
相反,在以下命令中,不接受的连接数 (192) 超过了 128 的限制。当网站遇到大量流量时,这很常见。为了获得最佳性能,您需要增加在操作系统和 NGINX 配置中可以排队等待 NGINX 接受的最大连接数。
Current listen queue sizes (qlen/incqlen/maxqlen)
Listen Local Address
0/0/128 *.12345
192/0/128 *.80
0/0/128 *.8080
2.调整操作系统(Tuning the Operating System)
将内核参数 net.core.somaxconn的值从其默认值 (128) 增加到足以容纳大量流量突发的值。在此示例中,它增加到 4096
- 对于 Linux:
- 运行命令:
sudo sysctl -w net.core.somaxconn=4096 - 使用文本编辑器将以下行添加到:
/etc/sysctl.confnet.core.somaxconn = 4096
- 运行命令:
3.调整 NGINX
如果将内核参数 somaxconn设置为大于 512 的值,请将 backlog参数更改为 NGINX 侦听指令以匹配:
server {
listen 80 backlog=4096;
# ...
}