• 进入"运维那点事"后,希望您第一件事就是阅读“关于”栏目,仔细阅读“关于Ctrl+c问题”,不希望误会!

Nginx http模块相关指令(一)

Nginx 彭东稳 9年前 (2016-04-21) 26734次浏览 已收录 0个评论

http{}配置段常用配置指令

http配置段中有些指令是http核心模块(ngx_http_core_module)引入的指令,有些指令是其他模块引入的指令。在http{}配置段中设置的指令对所有的server生效,如果有多个虚拟主机可以把http{}段的指令直接写入到独立的虚拟主机server配置段中,只对特定的server生效。先看默认的nginx.conf配置文件中http{}配置段的内容,然后讲指令:

http模块(ngx_http_core_module)

一、服务器端相关配置

1)include   /etc/nginx/mime.types;

include的指令主要是把其他配置文件加载成nginx能够读取到的配置,这里的mime.types主要是指明nginx可以支持的mime类型。MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展是一个互联网标准,它扩展了电子邮件标准,使其能够支持非ASCII字符、二进制格式附件等多种格式的邮件消息。正因如此,一些非英语字符消息和二进制文件,图像,声音等非文字消息才能在电子邮件中传输。此外,HTTP协议在0.9版本时还只能传输文本字符,但是在1.0版本中HTTP协议也使用了MIME的框架,标准被扩展为互联网媒体类型。因此,http也可以传输文本、图像、音频、视频以及其他应用程序专用的数据了,详情可以看维基百科MIME

2)default  application/octet-stream;

指定Nginx支持的默认MIME类型,其中application/octet-stream MIME类型表示可传输任意的二进制数据。常用MIME类型有:text(标准文本信息)、video(视频)、message(包装email消息)、application(二进制数据)、image(图片)、audio(音频或声音)等,想了解更多MIME类型请看MIME TYPE

3)tcp_nodelay

对Nginx长连接(keepalive)启用下,是否开启或关闭TCP_NODELAY功能。这个选项仅在将连接转变为长连接的时候才被启用。默认tcp协议有一个ngoi算法,当目标主机是同一个时,可以把多个很小的请求报文合并成单个报文进行发送,这样可以尽可能高地提高带宽利用率的和性能。但是这会带来另外一个小问题,如果客户端请求报文很小,那么服务器就会等待更多的报文过来一块发送给客户端,这样就会让客户端等待。此功能默认是开启的,可以选择关闭,浪费点带宽。

4)tcp_nopush

是否启用或关闭tcp_nopush这个套接字选项,其实TCP_NOPUSH套接字选项是FreeBSD的,在Linux上叫TCP_CORK套接字选项。这个选项仅在启用sendfile功能时才有用, 如果设置为on,就会将所有的http首部响应报文打放在同一个tcp报文发送给客户端。默认不启用,最好也不要启用。

二、文件优化相关配置

1)sendfile

用于启用或关闭sendfile()系统调用进行传输文件,默认为off;启用此功能可以保证静态文件不需要从用户空间转到内核空间进行发送,而是直接在内核空间打包发送。传统的read()/write()系统调用大概数据发送流程是通过DMA机制从硬盘–(读)–>内核空间缓存区–(读)–>用户空间缓存区–(写)–>内核空间socket相关缓冲区–>协议栈;从内核层用read系统调用读到用户层,再从用户层用write系统调用写到内核层,每一次用户层到内核层的进行一次上下文转换,这种代价是非常昂贵的。甚至在没有数据变化时这种复制尤其显得多余。如果nginx接受大量并发请求,这种系统调用就会非常频繁,服务器的性能就会下降。而sendfile系统调用则提供了一种减少以上多次数据复制,直接从硬盘–(读)–>内核空间缓存区–(读)–>内核空间socket相关缓冲区–>协议栈,然后发送给用户。sendfile() 数据复制是在一个文件描述符和另一个文件描述符之间,且这种操作都是在内核空间完成,nginx在支持了sendfile系统调用后,避免了内核层与用户层的上线文切换(content swith)工作,大大减少了系统性能的开销。最后说一下sendfile系统调用是一种文件传输的系统调用和kernel系统调用关系不大。可以使用man sendfile进程帮助查看。

2)sendfile_max_chunk

用于设置sendfile最大的chunk大小,其中size的值如果大于0,Nginx的每个worker进程每次调用sendfile()传输的数据量最大不能超过这个值。如果设置为0,则表示无限制,默认值为0。

3)aio

是否开启aio(异步IO),异步IO是Linux 5种IO模型中性能最好的一种IO模型。但要使aio生效需把directio设置为打开状况,并且如果aio生效,那么将自动不使用sendfile(),这在Linux下这是显然的,要么利用aio读到缓存区,要么利用sendfile()直接发送出去,两者不可兼用。

4)directio

如果按照如下指令这么设置:

如果某处请求的文件大于等于512k,那么将启用directio,从而aio生效,进而sendfile不生效; 如果某处请求的文件小于512k,那么将禁用directio,从而aio也就不生效,转而使用sendfile(),即sendfile生效。

这种设计貌似刚好把Linux下aio和sendfile两种机制的优点很好的结合起来使用。对于大文件采用aio,节省cpu,而对于小文件,采用sendfile,减少拷贝;并且对于大文件aio采用directio,避免挤占文件系统缓存,让文件系统缓存更多的小文件。从理论上来看,这种配置比较适合系统内存有限、小文件请求比较多、间隔有几个大文件请求的Web环境;如果内存足够大,那么应该充分利用文件系统缓存,而directio使得aio无法使用缓存是衡量最终是否需要采用aio的一个需要仔细考虑的因素;网上有人总结说nginx+aio很好,也有人说其很差,其实根据特定的系统环境和应用场景来做配置调节,才能达到性能的最优,nginx提供的 AIO 只是一套工具,没有固定的好与差之分,就看你能否恰当的用好它,但据nginx官网论坛来看,在linux系统的大部分场景下,目前因使用aio功能附加的限制而带来的实际效果估计并不太理想。

5)open_file_cache

用于配置文件缓存,Ningx可缓存:

1)打开文件的描述符,大小和修改时间;

2)目录查找结果;

3)文件查找时的错误结果,诸如“file not found”(文件不存在)、“no read permission”(无读权限)等等。

缓存这些内容有助于加快Nginx响应,如果一个文件找不到被缓存下来了,那么下一个用户再访问此文件将直接从内存返回结果给他。

指令有下列参数:

max – 设置缓存中元素的最大数量,当缓存溢出时,使用LRU(最近最少使用)算法删除缓存中的元素;

inactive – 设置超时,在这段时间内缓存元素如果没有被访问,将从缓存中删除。 默认超时是60秒;

off – 关闭缓存。

使用示例如下:

6)open_file_cache_errors

Nginx虽然可以缓存以上三种信息,但是对于其找不到路径或没有权限访问的文件,你可以选择缓存或者不缓存,如果开启open_file_cache默认是进行缓存的。

7)open_file_cache_valid

设置检查open_file_cache缓存的元素的时间间隔,默认是60s。

8)open_file_cache_min_uses

设置在由open_file_cache指令的inactive参数配置的超时时间内,文件应该被访问的最小number(次数)。如果访问次数大于等于此值,文件描述符会保留在缓存中,否则从缓存中删除。 没有被访问,缓存也没有意义。

二、客户端请求相关配置

1)keepalive_timeout

设置长连接的超时时间,第一个参数设置客户端的长连接在服务器端保持的最长时间(在此时间客户端未发起新请求,则长连接关闭)。 第二个参数为可选项,设置“Keep-Alive: timeout=time”响应头的值。 可以为这两个参数设置不同的值。“Keep-Alive: timeout=time”响应头可以被Mozilla和Konqueror浏览器识别和处理,MSIE浏览器在大约60秒后会关闭长连接。如果timeout的值为0表示禁止长连接。

简单说一下长连接的作用,早期web服务器通过HTTP协议传输的数据是以文本为主,一个请求可能就把所有要返回的数据取到,但是,现在要展现一张完整的页面需要很多个请求才能完成,如图片,JS,CSS等,如果每一个HTTP请求都需要新建并断开一个TCP,这个开销是完全没有必要的,开启HTTP Keep-Alive之后,能复用已有的TCP链接,当前一个请求已经响应完毕,服务器端没有立即关闭TCP链接,而是等待一段时间接收浏览器端可能发送过来的第二个请求,通常浏览器在第一个请求返回之后会立即发送第二个请求,如果某一时刻只能有一个链接,同一个TCP链接处理的请求越多,开启KeepAlive能节省的TCP建立和关闭的消耗就越多。当然通常会启用多个链接去从服务器器上请求资源,但是开启了Keep-Alive之后,仍然能加快资源的加载速度。HTTP/1.1之后默认开启Keep-Alive, 在HTTP的头域中增加Connection选项。当设置为Connection:keep-alive表示开启,设置为Connection:close表示关闭。

2)keepalive_requests

设置通过一个长连接可以处理的最大请求数。 请求数超过此值,长连接将关闭。

3)keepalive_disable

针对行为异常的浏览器关闭长连接功能。 browser参数指定那些浏览器会受到影响。 值为msie6表示在遇到POST请求时,关闭与老版MSIE浏览器建立长连接。 值为safari表示在遇到Mac OS X和类Mac OS X操作系统下的Safari浏览器和类Safari浏览器时,不与浏览器建立长连接。 值为none表示为所有浏览器开启长连接功能。

4)server_tokens

开启或关闭在错误信息的”Server”响应头中输出nginx版本号,应该关闭。

5)send_timeout

服务器发送响应报文的超时响应时间,默认为60s。

6)client_body_buffer_size

用来设定服务器接收客户端请求报文body的缓冲区大小,对于64位系统来说默认是16K;一旦客户端body部分超过此值,nginx就会把它移存到磁盘上面去,而不放在内存缓存区中,不然维护1万个连接就最少需要10000×16=160000=160M内存。16k已经不小了,但是对于那些允许用户上传或允许用户提交表单(表单较大)的业务,16K还是会显得有点小。

7)client_body_temp_path

上面说了,一点客户端body部分大于默认16k时,就会把body内容移存到磁盘上面去。那么这个指令就是用来定义存储客户端请求body的临时文件的目录和数量,最多可以有三级子目录层次结构(level 1,level 2,level 3),其中level 1、level 2、level 3表示一级目录、二级子目录、三级子目录;每个级别都是使用十六进制字符来表示,例如,在下面的结构:

其中1表示, 使用1个十六进制数字来表示级别1可以使用的子目录的数量和名称,我们知道十六进制数字一共有16个字符(0-F)。因此如果level 1使用1个字符,那么最多可以有16个一级子目录。其中2表示可以使用2个十六进制字符,也就是级别2上面可以有16X16等于256个子目录数量,但是注意这256个子目录的数量是相对于一个一级子目录所能拥有的,子目录是不能够共用的。所以总的二级子目录就是16X256个了,如果你把level 1的字符由1个变成2个,你可以算算有多少个二级子目录。

8)client_header_buffer_size size

设置读取客户端请求头部的缓冲容量。 对于大多数请求,1K的缓冲足矣。 但如果请求中含有的cookie很长,或者请求来自WAP的客户端,可能请求头不能放在1K的缓冲中。 如果从请求行,或者某个请求头开始不能完整的放在这块空间中,那么nginx将按照 large_client_header_buffers指令的配置分配更多更大的缓冲来存放。

三、对客户端请求数据大小限制

1)limit_except

对指定范围之外的其他方法进行限定,就是允许按请求的HTTP方法限制对某路径的请求。method用于指定不由这些限制条件进行过滤的HTTP方法,可选值有 GET、 HEAD、 POST、 PUT、 DELETE、 MKCOL、 COPY、MOVE、OPTIONS、PROPFIND、PROPPATCH、LOCK、UNLOCK或者PATCH。指定method为GET方法的同时,nginx会自动添加HEAD方法。 那么其他HTTP方法的请求就会由指令引导的配置块中的ngx_http_access_module 模块和ngx_http_auth_basic_module模块的指令来限制访问。如:

上面的例子表示将对除GET和HEAD方法以外的所有HTTP方法的请求进行访问限制。

2)limit_rate

限制向客户端传送响应的速率限制。参数rate的单位是字节/秒,设置为0将关闭限速。 nginx按连接限速,所以如果某个客户端同时开启了两个连接,那么客户端的整体速率是这条指令设置值的2倍。

3)limit_rate_after

设置不限速传输的响应大小,当传输量大于此值时,超出部分将限速传送,小于设置值时不限速。比如:

关于核心模块的更多指令可以看淘宝翻译的文章官方文档


如果您觉得本站对你有帮助,那么可以支付宝扫码捐助以帮助本站更好地发展,在此谢过。
喜欢 (1)
[资助本站您就扫码 谢谢]
分享 (0)

您必须 登录 才能发表评论!