本文将讲述如何配置 nginx 提供静态内容服务,如何定义文件路径,以及如何设置 index 文件。
目录:
- root 目录以及 index 文件
- try_file 指令
- 优化 nginx 的速度
- 开启 sendfile
- 开启 tcp_nopush
- 开启 tcp_nodelay
- 优化 Backlog Queue
- 测量 Listen Queue
- 调优系统参数
- 调整 nginx 配置参数
root 目录以及 index 文件
root 指令用于指定 nginx 查找文件的基础路径,nginx 所提供的文件都在该路径之下。
nginx 将请求的 URI 追加到 root 指令所指定的路径之后,形成最终的文件访问路径。root 指令可放置于 http、server 以及 location 上下文中。在下面的例子中,root 指令定义在 server 上下文中,如果一个 location 没有自己设置 root 定义,它就从 server 区块继承 root 指令的定义:
server {
root /www/data;
location / {
}
location /images/ {
}
location ~ \.(mp3|mp4) {
root /www/media;
}
}
基于这份配置,如果 URI 以 /images/ 起始,nginx 在 /www/data/images/ 路径下查找文件。但如果 URI 以 .mp3 或 .mp4 为后缀,nginx 会在 /www/media 中查找文件,这是因为正则表达式匹配的 location 有更高的优先级。
如果请求以 / 为结尾,nginx 将其视为对一个目录的请求,并尝试在该目录中找到 index 文件。index 指令定义了 index 文件的名字(默认的名字为 index.html)。如果一个请求的 URI 为 /images/some/path/
,nginx 尝试找到 /www/data/images/some/path/index.html
文件,并返回给客户端。如果该文件不存在,nginx 默认返回 404 (Not found) 错误。如果希望这时 nginx 返回一个自动生成的目录列表而不是返回 404 错误,使用 autoindex 指令进行设置:
location /images/ {
autoindex on;
}
在 index 指令中,可设置多个文件名,nginx 根据设置的顺序依次查找,并返回第一个找到的文件:
location / {
index index.$geo.html index.htm index.html;
}
$geo 变量是一个自定义的变量,由 geo 指令所定义。该变量的值依赖于客户端的IP地址。
当 nginx 找到 index 文件后,会做一个内部重定向,新的 URI 是将 index 文件的文件名追加到原来的 URI 上。进行内部重定向之后,nginx 对新的 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
文件存在,这时,做完内部重定向后的新的URI 为 /path/index.php
,将被第二个 location 所匹配,该请求最终被转发给后端服务器。
try_file 指令
try_files 指令用于检测指定的文件或目录是否存在,如果不存在,就做内部重定向,或者返回指定的状态码。
例如,使用 try_files 指令和 $uri 变量可以检测一个请求的 URI 所对应的文件是否存在:
server {
root /www/data;
location /images/ {
try_files $uri /images/default.gif;
}
}
此例中,如果一个请求的 URI 对应的文件不存在,比如 URI 为 /images/somefile.png
,对应的文件路径为 /www/data/images/somefile.png
,如果这个文件不存在,try_files 指令将原来的 URI 内部重定向到 /images/default.gif
,nginx 进行重新匹配查找,最后返回 /www/data/images/default.gif
文件。
try_files 指令的最后一个参数可以是一个状态码(比如 =404),或者是一个 location 的名字。在下面的例子中,如果 try_files 指令的所有参数都没有解析为一个存在的文件或目录,那么就返回 404 错误:
location / {
try_files $uri $uri/ $uri.html =404;
}
在下面的例子中,如果原始的 URI,以及 URI/ 都不能解析为一个存在的文件或目录,该请求将被重定向至一个命名的 location,该 location 将把请求转发给后端服务器:
location / {
try_files $uri $uri/ @backend;
}
location @backend {
proxy_pass http://backend.example.com;
}
可观看 Content Caching,学习如何极大提升 web 站点的性能,深入了解 nginx 的缓存功能。
优化 nginx 的速度
对于提供内容服务来说,加载速度是一个关键的性能指标。通过对 nginx 做一些微小的配置,可能会极大提升 nginx 的性能,帮助 nginx 优化到接近最佳的状态。
开启 sendfile
默认情况下,nginx 自己负责处理文件的发送,在发送文件时,它将文件拷贝的 tcp 发送缓冲。
开启 sendfile 指令,会消除将数据复制到发送缓冲这一步骤,它使数据可以直接从一个文件描述符复制到另一个文件描述符。另外,为防止一个快速的连接完全占用 worker 进程,可限制一个 sendfile() 系统调用可以传递的数据量大小,使用 sendfile_max_chunk 指令:
location /mp3 {
sendfile on;
sendfile_max_chunk 1m;
...
}
开启 tcp_nopush
tcp_nopush 指令联合 sendfile on 一起使用,这时,当 nginx 通过 sendfile 获取到数据块之后,nginx 立即发送 HTTP 响应首部。
location /mp3 {
sendfile on;
tcp_nopush on;
...
}
开启 tcp_nodelay
tcp_nodelay 指令允许对 Nagle’s algorithm 进行覆盖。该算法被设计用于解决在低速网络中发送小数据报文的问题。该算法将一定数量的小报文整合为一个大数据报文,并以 200ms 的延迟发送该报文。到了现在的时代,当提供很大的静态文件时,可以无需在意报文的大小,可以立即发送数据报文。该延迟也会影响在线应用(ssh,在线游戏,在线交易)。
tcp_nodelay 指令默认设置为 on,意味着停止使用 Nagle’s algorithm 算法。tcp_nodelay 只用于持久连接中:
location /mp3 {
tcp_nodelay on;
keepalive_timeout 65;
...
}
优化 Backlog Queue
nginx 最重要的一个能力是可以快速的处理访问连接。
一般对于连接的处理是这样的:当一个连接建立之后,它将被放入监听套接字的 listen 队列之中。在普通的访问压力下,这个队列很短或者根本没有这个队列。但如果在高的访问压力下,这个队列可能会急速地增长,从而引起性能抖动,连接丢失,或访问延迟的问题。
测量 Listen Queue
执行命令:
netstat -Lan
译注:这是 BSD 环境下 netstat,Linux 下的 netstat 输出有所不同
命令输出可能如下:
Current listen queue sizes (qlen/incqlen/maxqlen)
Listen Local Address
0/0/128 *.12345
10/0/128 *.80
0/0/128 *.8080
该输出显示:监听端口 80 上有 10 个未接受的连接请求,其队列上限为 128,这是一般访问压力下的请求。
访问压力较大时,可能输出如下:
Current listen queue sizes (qlen/incqlen/maxqlen)
Listen Local Address
0/0/128 *.12345
192/0/128 *.80
0/0/128 *.8080
显示有 192 个未接受的连接请求,超出了 128 的上限值。当一个 web 站点访问压力大时,这是很常见的输出。为了得到优化的性能,你需要增加等待队列的上限值,为此我们需要调整操作系统的参数以及 nginx 的配置参数。
调优系统参数
为了应对访问高峰流量,调整 net.core.somaxconn 键值的值(默认为 128):
对于 FreeBSD,执行:
sudo sysctl kern.ipc.somaxconn=4096
对于 Linux,执行:
sudo sysctl -w net.core.somaxconn=4096
打开 /etc/sysctl.conf 文件
vi /etc/sysctl.conf
添加一行内容如下:
net.core.somaxconn = 4096
调优 nginx
如果你设置了 somaxconn 值为大于 512 的值,你需要修改 listen 指令的 backlog 参数与之匹配:
server {
listen 80 backlog 4096;
# The rest of server configuration
}
版权信息:
*本文编译自 nginx.com
网友评论