详解Nginx 静态文件服务配置及优化
根目录和索引文件
root指令指定将用于搜索文件的根目录。为了获取所请求文件的路径,NGINX将请求URI附加到root指令指定的路径。该指令可以放在http{},server{}或location{}上下文中的任何级别。在下面的示例中,为虚拟服务器定义了root指令。它适用于未包含根指令的所有location{}块,以显式重新定义根:
server{ root/www/data; location/{ } location/images/{ } location~\.(mp3|mp4){ root/www/media; } }
在这里,NGINX针对/images/开头的URI将在文件系统的/www/data/images/目录中搜索相应文件。如果URI以.mp3或.mp4扩展名结尾,则NGINX会在/www/media/目录中搜索该文件,因为它是在匹配的位置块中定义的。
如果请求以/结尾,则NGINX将其视为对目录的请求,并尝试在目录中查找索引文件。index指令定义索引文件的名称(默认值为index.html)。要继续该示例,如果请求URI是/images/some/path/,则NGINX会返回文件/www/data/images/some/path/index.html(如果存在)。如果没有,NGINX默认返回HTTP404错误(未找到)。要配置NGINX以返回自动生成的目录列表,请在autoindex指令中包含on参数:
location/images/{ autoindexon; }
你可以在index指令中列出多个文件名。NGINX按指定的顺序搜索文件并返回它找到的第一个文件。
location/{ indexindex.$geo.htmlindex.htmindex.html; }
这里使用的$geo变量是通过geo指令设置的自定义变量。变量的值取决于客户端的IP地址。
要返回索引文件,NGINX会检查它是否存在,然后对通过将索引文件的名称附加到基础URI上获得的新URI进行内部重定向。内部重定向导致对位置的新搜索,并且可能最终位于另一个位置,如以下示例所示:
location/{ root/data; indexindex.htmlindex.php; } location~\.php{ fastcgi_passlocalhost:8000; #... }
这里,如果请求中的URI是/path/,并且/data/path/index.html不存在但/data/path/index.php存在,则内部重定向到/path/index.php将映射到第二个位置。结果,请求被代理。
尝试几种选择
try_files指令可用于检查指定的文件或目录是否存在;NGINX会进行内部重定向,如果没有,则返回指定的状态代码。例如,要检查对应于请求URI的文件是否存在,请使用try_files指令和$uri变量,如下所示:
server{ root/www/data; location/images/{ try_files$uri/images/default.gif; } }
该文件以URI的形式指定,使用在当前位置或虚拟服务器的上下文中设置的根或别名指令进行处理。在这种情况下,如果对应于原始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_passhttp://backend.example.com; }
有关更多信息,请观看内容缓存网络研讨会,了解如何显着提高网站性能,并深入了解NGINX的缓存功能。
优化服务内容的性能
加载速度是提供任何内容的关键因素。对NGINX配置进行微小优化可以提高生产力并帮助实现最佳性能。
启用sendfile
默认情况下,NGINX会自行处理文件传输,并在发送之前将文件复制到缓冲区中。启用sendfile指令消除了将数据复制到缓冲区的步骤,并允许将数据从一个文件描述符直接复制到另一个文件描述符。或者,为了防止一个快速连接完全占用工作进程,可以使用sendfile_max_chunk指令限制单个sendfile()调用中传输的数据量(在本例中为1MB):
location/mp3{ sendfileon; sendfile_max_chunk1m; #... }
启用tcp_nopush
将tcp_nopush指令与sendfileon;指令一起使用。这使得NGINX可以在sendfile()获取数据块之后立即在一个数据包中发送HTTP响应头。
location/mp3{ sendfileon; tcp_nopushon; #... }
启用tcp_nodelay
tcp_nodelay指令允许覆盖Nagle的算法,该算法最初设计用于解决慢速网络中小数据包的问题。该算法将许多小数据包合并为一个较大的数据包,并以200毫秒的延迟发送数据包。如今,在提供大型静态文件时,无论数据包大小如何,都可以立即发送数据。延迟也会影响在线应用程序(ssh,在线游戏,在线交易等)。默认情况下,tcp_nodelay指令设置为on,这意味着禁用了Nagle的算法。此指令仅用于keepalive连接:
location/mp3{ tcp_nodelayon; keepalive_timeout65; #... }
优化积压队列
其中一个重要因素是NGINX可以多快地处理传入连接。一般规则是在建立连接时,将其放入侦听套接字的"listen"(监听)队列中。在正常负载下,队列很小或根本没有队列。但是在高负载下,队列会急剧增长,导致性能不均匀,连接中断,延迟增加。
显示积压队列使用命令netstat-Lan来显示当前监听队列。输出可能如下所示,它显示在端口80上的监听队列中,有10个未接受的连接,这些连接针对配置的最多128个排队连接。这种情况很正常。
Currentlistenqueuesizes(qlen/incqlen/maxqlen) ListenLocalAddress 0/0/128*.12345 10/0/128*.80 0/0/128*.8080
相反,在以下命令中,未接受的连接数(192)超过了128的限制。当网站流量很大时,这种情况很常见。要获得最佳性能,需要在操作系统和NGINX配置中增加可以排队等待NGINX接受的最大连接数。
Currentlistenqueuesizes(qlen/incqlen/maxqlen) ListenLocalAddress 0/0/128*.12345 192/0/128*.80 0/0/128*.8080
调整操作系统
将net.core.somaxconn内核参数的值从其默认值(128)增加到足以容纳大量流量的值。在这个例子中,它增加到4096。
- FreeBSD的命令为sudosysctlkern.ipc.somaxconn=4096
- Linux的命令为1.sudosysctl-wnet.core.somaxconn=40962.将net.core.somaxconn=4096加入到/etc/sysctl.conf文件中。
调整NGINX
如果将somaxconn内核参数设置为大于512的值,请将backlog参数增加在NGINXlisten指令以匹配修改:
server{ listen80backlog=4096; #... }
©文章翻译自NginxServingStaticContent,部分做了语义调整。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。