Nginx中文文档-ngx_http_core_module(A-C)

本文档包含以下指令:aio、aio_write、alias、chunked_transfer_encoding、client_body_buffer_size、client_body_in_file_only、client_body_in_single_buffer、client_body_temp_path、client_body_timeout、client_header_buffer_size、client_header_timeout、client_max_body_size、connection_pool_size

aio

语法:aio on | off | threads [=pool];
默认:aio off;
上下文:http, server, location
版本:0.8.11+

FreeBSD和Linux系统上开启/关闭异步文件io:

location /video/ {
    aio            on;
    output_buffers 1 64k;
}

在FreeBSD上,AIO从FreeBSD 4.3起开始支持。AIO可以静态的链接到内核中:
options VFS_AIO
或作为加载为内核可加载模块:
kldload aio
在Linux上,AIO从2.6.22内核版本起开始支持。需要同时启用directio,否则读取仍是阻塞的:

location /video/ {
    aio            on;
    directio       512;
    output_buffers 1 128k;
}

在Linux上,directio只能用于读取512字节边界对齐的块(如果是XFS文件系统则是4K)。文件的末尾未对齐会使用阻塞模式进行读取。同样,对于字节范围的请求和不是从文件开始的FLV请求在开头和结尾未对齐的数据,读取也是阻塞的。
在Linux上,当AIO和sendfile同时启用时,AIO会作用于文件大于或等于那些在directio指令中指定的大小,而sendfile会作用于小于directio中指定大小的文件或directio是禁用时。

location /video/ {
    sendfile       on;
    aio            on;
    directio       8m;
}

最后,文件可以使用多线程进行读取和发送(1.7.11版起),不会阻塞工作进程。

location /video/ {
    sendfile       on;
    aio            threads;
}

读取和发送文件操作将在指定的线程池中执行。如果忽略了线程池名称,则使用默认的“default”作为名称,名称可以使用变量定义:
aio threads=pool$disk
默认情况下,多线程是禁用的,需要通过–with-threads配置参数启用。目前,多线程只适用于epoll、kqueue和eventport方法。多线程发送文件只在Linux上支持。
参见sendfile指令。

aio_write

语法:aio_write on | off
默认:aio_write off
上下文:http, server, location
版本:1.9.13+

如果开启了aio指令,该指令指定了是否使用它进行写文件操作。目前,只有在使用aio线程并且是写的是从被代理的服务器上收到的数据的临时文件时,该功能可用。

alias

语法:alias path
默认:–
上下文:location

为指定的location定义一个替代写法。例如,有如下配置:

location /i/ {
    alias /data/w3/images/;
}

在请求“/i/top.gif”时,将会响应/data/w3/images/top.gif文件。
path的值可以包含变量(除了$document_root和$realpath_root)。
如果alias用在一个正则表达式定义的location中,则这个正则表达式需要有捕获,且alias必须要提到这个捕获,例如:

location ~ ^/users/(.+\.(?:gif|jpe?g|png))$ {
    alias /data/w3/images/$1;
}

当location匹配了alias指令的最后一部分时,最好用root替换,例如
不好的写法

location /images/ {
    alias /data/w3/images/;
}

建议的写法

location /images/ {
    root /data/w3;
}

chunked_transfer_encoding

语法:chunked_transfer_encoding on | off;
默认:chunked_transfer_encoding on;
上下文:http, server, location

允许禁用HTTP1.1的chunked编码传输。它会在软件不能支持chunked编码时起到作用,虽然标准中是需要支持的。

client_body_buffer_size

语法:client_body_buffer_size size;
默认:client_body_buffer_size 8k|16k;
上下文:http, server, location

设置读取客户端请求体的缓冲区大小。如果请求体超出缓冲区大小,整个请求或请求的一部分会被写入到临时文件中。默认情况下,缓冲区大小等于两页内存大小。32位平台和x86-64平台上是8k,其他64位平台上是16k。

client_body_in_file_only

语法:client_body_in_file_only on | clean | off;
默认:client_body_in_file_only off;
上下文:http, server, location

决定nginx是否将整个请求内容保存到文件中。这个指令可以在调试期间或当使用了$request_body_file变量或ngx_http_perl_module模块的$r->request_body_file方法时使用。
当这个值为on时,临时文件不会在请求结束后自动删除。
值为clear是,临时文件会在请求处理后删除。

client_body_in_single_buffer

语法:client_body_in_single_buffer on | off;
默认:client_body_in_single_buffer off;
上下文:http, server, location

该指令定义了nginx是否需要将整个请求保存在单个的缓冲区中。建议在使用$request_body变量时开启,这样可以保存相关复制操作数。

client_body_temp_path

语法:client_body_temp_path path [level1 [level2 [level3]]];
默认:client_body_temp_path client_body_temp;
上下文:http, server, location

指定一个存放请求的临时目录。最多可以用指定目录的3级子目录。例如,在下面的配置中:
client_body_temp_path /spool/nginx/client_temp 1 2;#1为第一级的位数,2为第二级的位数
一个临时文件可能是这样:
/spool/nginx/client_temp/7/45/00000123457

client_body_timeout

语法:client_body_timeout time;
默认:client_body_timeout 60s;
上下文:http, server, location

定义读取客户端请求的超时时间。超时时间只是针对两次连续读操作的时间,并不是整个传输请求的时间。如果客户端在这期间没有传任何数据,则会返回408错误码(请求超时)。

client_header_buffer_size

语法:client_header_buffer_size size;
默认:client_header_buffer_size 1k;
上下文:http, server

设置读取客户端请求头的缓冲区大小。大多数请求1K是够用了。但是,如果请求有很长的cookies或来自一个WAP客户端,1K的大小就不合适了。如果请求头大小超过缓冲区,会分配large_client_header_buffers指令中定义的大小。

client_header_timeout

语法:client_header_timeout time;
默认:client_header_timeout 60s;
上下文:http, server

定义读取客户端请求头的超时时间。如果客户端在此时间内没有发送全部请求头,会返回408状态码。

client_max_body_size

语法:client_max_body_size size;
默认:client_max_body_size 1m;
上下文:http, server, location

定义允许的最大请求体大小,这个大小是在请求头Content-Length中定义的。如果请求超过了设置的值,会返回413错误码。请注意,浏览器不会正确的显示这个错误。将size设置为0,可以禁止检查请求体的大小。

connection_pool_size

语法:connection_pool_size size;
默认:connection_pool_size 256|512;
上下文:http, server

允许精确的控制每一个连接的内存分配。这个指令对性能影响很小,不要广泛的使用。默认情况下,在32位平台上该值为256字节,在64位平台上该值为512字节。
在1.9.8版本前,所有的平台中默认值都为256.

nginx配置https服务器

本文介绍如何将nginx配置成一个https服务器。

配置https服务器,需要在listen指令后面添加ssl,并添加服务器证书和私钥:

server {
    listen              443 ssl;
    server_name         www.example.com;
    ssl_certificate     www.example.com.crt;
    ssl_certificate_key www.example.com.key;
    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers         HIGH:!aNULL:!MD5;
    ...
}

服务器证书是一个公开的实体,它将会被发送到所有连接服务器的客户端上。私钥是一个安全的实体,应该有着严格的访问控制权限,但必须能被nginx读取,私钥和证书可以用同一个文件存储:

ssl_certificate     www.example.com.cert;
ssl_certificate_key www.example.com.cert;

这种情况下,权限控制仍然是严格的,即使证书和私钥存在同一个文件里,但只有证书会被发送到客户端。
ssl_protocols和ssl_ciphers指令限制了使用的加密算法和版本,只能用比较健壮的加密算法。默认情况下,nginx使用“ssl_protocols TLSv1 TLSv1.1 TLSv1.2”和“ssl_ciphers HIGH:!aNULL:!MD5”,因此一般不需要特意指定。注意,这个默认值已经改变了多次,详见文章底部的兼容性。
https服务器优化
SSL操作会增加CPU的消耗。在多核CPU的操作系统中应使用多个工作进程,并且数量不少于可用CPU的核心数。CPU最密集的操作是SSL握手阶段。有两种方法使这种操作降到最低:第一是开启keep_alive,让多个请求复用一个连接;第二是复用SSL session以避免并行的连接和并发的连接进行SSL握手。通过ssl_session_cache指令配置SSL session,这些session存储在缓存中供工作进程共享使用。1M的缓存里有4000个会话信息。默认的缓存超时时间是5分钟,可以通过ssl_session_timeout指令增加。下面是一个运行在多核操作系统使用了10M缓存的简单配置方法:

worker_processes auto;

http {
    ssl_session_cache   shared:SSL:10m;
    ssl_session_timeout 10m;

    server {
        listen              443 ssl;
        server_name         www.example.com;
        keepalive_timeout   70;

        ssl_certificate     www.example.com.crt;
        ssl_certificate_key www.example.com.key;
        ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers         HIGH:!aNULL:!MD5;
        ...

SSL证书链
一些浏览器会要求证书是可信的CA颁布,而另一些浏览器却不理会。这种情况的产生是由于使用的证书是中间人进行颁发的,而这个颁发机构并没有加入到浏览器的信任根上,这时应该将信任根添加到证书中:
$ cat www.example.com.crt bundle.crt > www.example.com.chained.crt
最终的配置文件如下:

server {
    listen              443 ssl;
    server_name         www.example.com;
    ssl_certificate     www.example.com.chained.crt;
    ssl_certificate_key www.example.com.key;
    ...
}

如果证书和bundle的顺序反了,nginx将会在启动时报错:

SSL_CTX_use_PrivateKey_file(” … /www.example.com.key”) failed
(SSL: error:0B080074:x509 certificate routines:
X509_check_private_key:key values mismatch)

浏览器总是保存中间的可信证书,所以很多浏览器不会理会没有证书链的问题。
配置一个包含HTTP/HTTPS服务器
可以将HTTP和HTTPS配置到一个服务器上:

server {
    listen              80;
    listen              443 ssl;
    server_name         www.example.com;
    ssl_certificate     www.example.com.crt;
    ssl_certificate_key www.example.com.key;
    ...
}

0.7.14版本之前,不能像上面那样配置SSL。只能用ssl指令完整的配置,无法实现一个server上运行HTTPS和HTTP。现在增加了ssl参数解决了这个问题,所以ssl指令已经在新版本中不推荐使用。
基于名称的HTTPS服务器
当多个HTTPS服务器在同一个IP上监听端口时,就会出现一个普遍的问题:

server {
    listen          443 ssl;
    server_name     www.example.com;
    ssl_certificate www.example.com.crt;
    ...
}

server {
    listen          443 ssl;
    server_name     www.example.org;
    ssl_certificate www.example.org.crt;
    ...
}

上面的配置使用默认的证书,即www.example.com,并不理会服务器名称,这是SSL的行为。SSL在建立连接时nginx还不知道主机名,所以会提供默认的证书。
原始粗暴的解决方法是,通过监听不同的IP地址解决:

server {
    listen          192.168.1.1:443 ssl;
    server_name     www.example.com;
    ssl_certificate www.example.com.crt;
    ...
}

server {
    listen          192.168.1.2:443 ssl;
    server_name     www.example.org;
    ssl_certificate www.example.org.crt;
    ...
}

一个证书多个名称
有其他的办法共享同一个IP地址,建立多个HTTPS服务器,但所有的方法都有些弊端。一个方法是将多个名称加到证书的SubjectAltName域中,如www.example.com和www.example.org,但长度有限制。
另一种方法是使用通配符名称,如*.example.org。这种证书可以认证所有的子域名,但只能有一级。它能匹配www.example.org但不能匹配example.org和www.sub.example.org。这两种方法可以混合使用。如example.org 和 *.example.org
最好将证书的配置放到http块下面,以便其他的服务器可以继承证书:

ssl_certificate     common.crt;
ssl_certificate_key common.key;

server {
    listen          443 ssl;
    server_name     www.example.com;
    ...
}

server {
    listen          443 ssl;
    server_name     www.example.org;
    ...
}

兼容性

  • The SNI support status has been shown by the “-V” switch since 0.8.21 and 0.7.62.
  • listen指令的ssl参数从0.7.14被支持,0.8.21版本之前它只能与default参数一同定义
  • SNI has been supported since 0.5.32.
  • 共享SSL会话缓存功能从0.5.6版本开始支持
  • 1.9.1及以后的版本:默认SSL协议为TLSv1, TLSv1.1, and TLSv1.2(如果openssl库支持)
  • 0.7.65, 0.8.19及更高版本:默认的SSL协议为SSLv3, TLSv1, TLSv1.1, and TLSv1.2(如果openssl库支持)
  • 0.7.64, 0.8.18及更早版本:默认的SSL协议为SSLv2, SSLv3, and TLSv1
  • 1.0.5及更高版本:默认SSL加密算法为“HIGH:!aNULL:!MD5”
  • 0.7.65, 0.8.20及跟高版本:默认SSL加密算法为“HIGH:!ADH:!MD5”
  • 0.8.19版本:默认的SSL加密算法为“ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM”
  • 0.7.64, 0.8.18及更早版本:默认SSL加密算法为“ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP”