4.1 根目录及索引文件
root
指令用于设置服务器查找文件的根目录,可用于http
, server
和 location
。示例如下:
server {
root /www/data;
location / {
}
location /images/ {
}
location ~ \.(mp3|mp4) {
root /www/media;
}
}
如果请求URL以/images/
开头,那么Nginx就会在服务器的/www/data/images/
目录查找请求的文件。如果请求URL以.mp3
或.mp4
结尾,那么Nginx就会在服务器的/www/media/
目录查找请求的文件。因为这条location
中root
指令重新设定了查找根目录。
如果请求URL以/
结尾(未指定具体的文件名),Nginx会认为客户端在请求访问一个目录,并在该目录中查找索引文件。默认的索引文件为index.html
,可以通过index
指令重新设定索引文件。如果索引文件不存在,Nginx默认会返回404(Not found)
错误代码。
也可以通过如下配置,让Nginx自动生成文件目录:
location /images/ {
autoindex on;
}
可以通过index
指令指定不同的索引文件,示例如下:
location / {
index index.htm index.html;
}
Nginx在查找索引文件时,先检查索引文件是否存在,然后在内部重定向到该索引文件的全路径的URI,从而导致对location的重新匹配。如下所示,假设请求URI为/path/
,并且/data/path/index.html
不存在,而 /data/path/index.php
存在。那么内部重定向将最终导致第二个location匹配该请求。
location / {
root /data;
index index.html index.php;
}
location ~ \.php {
fastcgi_pass localhost:8000;
...
}
4.2 尝试匹配
try_file
可用于检查请求的资源是否存在,并做内部重定向,或返回一个状态代码。如下所示,Nginx根据root和请求uri检查资源是否存在,如果不存在,就发起一个内部重定向到/www/data/images/default.gif
访问。
server {
root /www/data;
location /images/ {
try_files $uri /images/default.gif;
}
}
try_file
的第二个参数也可以是一个状态码(以=开头),或一个location的名字。如下所示,如果请求的资源都不存在,就会返回一个404错误。
location / {
try_files $uri $uri/ $uri.html =404;
}
在下面的例子中,如果请求资源不存在,就会跳转到一个命名的location。
location / {
try_files $uri $uri/ @backend;
}
location @backend {
proxy_pass http://backend.example.com;
}
4.3 优化配置
启用sendfile
Nginx默认自己处理文件传输,在传输文件前,先将文件拷贝到缓冲区。启用sendfile指令,可以不用先将文件拷贝到缓冲区,而直接将文件拷贝到另外一个文件描述符。另一方面,也可以通过sendfile_max_chunk
设置文件传输的大小,从而避免占用整个worker进程。示例如下:
location /mp3 {
sendfile on;
sendfile_max_chunk 1m;
...
}
启用tcp_nopush
tcp_nopush
指令与sendfile
指令一起使用,可以让Nginx在同一个数据包里发送HTTP响应头部。
location /mp3 {
sendfile on;
tcp_nopush on;
...
}
启用tcp_nodelay
tcp_nodelay
指令用于禁用Nagle算法,该算法依赖于大量小数据包来处理在低速网络环境下传输问题,数据包传输时会有200毫秒延迟。现代网络环境下,可以立即传输大文件而无关数据包大小。这时,延迟就可能影响到在线应用(如ssh,在线游戏,在线交易等)。tcp_nodelay
指令可以禁用Nagle算法,该指令仅适用于保持连接的情况。示例如下:
location /mp3 {
tcp_nodelay on;
keepalive_timeout 65;
...
}
4.4 优化队列
Nginx一个重要的特性是可以快速处理连接的能力。连接建立后,一般会被放到监听端口的队列里。在普通负载的情况下,一般是一个低级的队列,或根本没有队列。在高负载的情况下,队列会大幅增长,从而导致性能不均衡、连接丢失以及延迟。
评估队列
第一步先通过下面命令来评估队列情况:
netstat -Lan
该命令输出如下:
Current listen queue sizes (qlen/incqlen/maxqlen)
Listen Local Address
0/0/128 *.12345
10/0/128 *.80
0/0/128 *.8080
如上所示,80端口上有一个最大长度为128的队列,该队列有10个未处理的连接请求。这是在普通负载下的情况。
但也可能是下面这种情况:
Current listen queue sizes (qlen/incqlen/maxqlen)
Listen Local Address
0/0/128 *.12345
192/0/128 *.80
0/0/128 *.8080
如上所示,80端口上有192个未处理的连接请求,超过了队列的长度范围。在高负载时,这是很常见的情况。为了优化性能,需要增加队列的最大长度,来满足请求数量。这需要同时优化操作系统和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,需要设置backlog
参数如下:
server {
listen 80 backlog=4096;
# The rest of server configuration
}
网友评论