本文着重介绍Nginx的使用方法,主要包含Nginx进程管理,常用配置和TCP内核参数优化等内容。
Nginx进程管理
Nginx常用配置
参数名
取值
默认值或示例
描述
daemon
on|off
daemon on;
是否以守护进程方式启动
master_process
on|off
master_process on;
是否以master/worker方式工作
error_log
/path/file level
error_log logs/error.log error;
error日志的设置
debug_points
stop|abort
是否处理几个特殊的调试点
debug_connection
[IP|CIDR]
仅对指定的ip输出debug级别的日志
worker_rlimit_core
size
限制coredump文件的大小
working_directory
path
worker进程的工作目录
1 2 3 4 5 6 debug_connection 这个配置项属于事件类配置,它必须放到events {...}中才能生效 events { debug_connection 10.224.66.14 ; debug_connection 10.224.57.0 /24 ; }
参数名
取值
默认值或示例
描述
env
VAR|VAR=VALUE
定义环境变量
include
/path/file
include mime.types; include vhost/*.conf;
嵌入其他配置文件
pid
/path/file
pid logs/nginx.pid;
pid文件的路径
user
username [groupname]
user nobody nobody;
worker进程运行的用户及用户组
worker_rlimit_nofile
limit
限制worker进程最大可以打开的句柄数量
worker_rlimit_sigpending
limit
限制信号队列
参数名
取值
默认值或示例
描述
worker_processes_number
number
worker_processes_number 1;
设置worker进程的数量
worker_cpu_affinity
cpumask [cpumask…]
worker_processes_number 4; worker_cpu_affinity 1000 0100 0010 0001;
绑定worker进程到指定cpu核心
ssl_engine
device
ssl硬件加速
timer_resolution
time
系统调用gettimeofday的执行频率
work_priority
nice
work_priority 0;
设置worker进程的nice优先级
参数名
取值
默认值或示例
描述
accept_mutex
[on|off]
accept_mutex on;
是否打开accept锁
lock_file
/path/file
lock_file logs/nginx.lock;
lock文件的路径,文件锁
accept_mutex_delay
Nms
accept_mutex_delay 500ms;
accept锁后到真正建立连接的延迟时间
multi_accept
[on|off]
multi_accept off;
批量建立新连接
use
[kqueue|rtsig|epoll| /dev/poll|select|poll|eventport]
选择事件模型
worker_connections
number
每个worker的最大连接数
1 2 3 4 accept_mutex master进程监听web端口,fork出多个子进程,这些子进程开始同时监听同一个web端口。假如,在某一时刻,所有的worker子进程都休眠且等待新连接的系统调用(epoll_wait),这时有一个用户向服务端发起连接,内核收到TCP的SYN包时,会激活所有的休眠worker子进程,此时只有最先开始执行accept的子进程可以成功建立新连接,而其他worker子进程都会accept失败,这些失败accept失败的子进程被内核唤醒是不必要的,这个现象被称为"惊群"。 通过设置accept_mutex可以保证某一时刻仅能有一个子进程监听web端口(只有调用ngx_trylock_accept_mutex方法后,当前worker进程才会去试着监听web端口),从而解决"惊群"问题。 如关闭accept_mutex,建立TCP连接的耗时会更短,但worker进程之间的负载会非常不均衡。
1 2 accept_mutex_delay 如果一个worker进程试图取accept锁没有取到,它至少等待accept_mutex_delay定义的时间间隔后才能再次试图取锁。
1 2 multi_accept 当事件模型通知有新连接时,尽可能对本次调度中客户端发起的所有TCP请求都建立连接。
参数名
取值
默认值或示例
描述
listen
address:port
示例见补充
监听端口
server_name
“”
主机名称
server_name_hash_bucket_size
size
32|64|128
每个散列桶占用的内存大小
server_name_hash_max_size
size
512
影响散列表的冲突率
server_name_in_redirect
on|off
on
重定向主机名称的处理
location
匹配用户请求中的uri
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 listen 示例: listen 127.0.0.1:8000; listen 127.0.0.1; listen 8000; listen *:8000; listen localhost:8000; ipv6: listen [::]:8000; listen [fe80::1]; listen [:::a8c9:1234]:80; 增加参数: listen 443 default_server ssl; listen 127.0.0.1 default_server accept_filter=dataready backlog=1024; 参数描述: default: 将所在的server块作为整个web服务的默认server块。如果没有设置那么将会以nginx.conf中找到的第一个server块作为默认的server块。当一个请求无法匹配配置文件中的所有主机的域名时,就会选用默认的虚拟主机。 default_server: 同上。 backlog=num: 表示TCP中backlog队列的大小。默认为-1,表示不予设置。在TCP建立三次握手过程中,进程还没有开始处理监听句柄,这是backlog队列会放置这些新连接。如果backlog队列已满,还有新的客户端试图通过三次握手建立TCP连接,这时客户端将会建立连接失败。 rcvbuf=size: 设置监听句柄的SO_RCVBUF参数。 sndbuf=size: 设置监听句柄的SO_SNDBUF参数。 accept_filter: 设置accept过滤器,只对FreeBSD系统有用。 deferred: 在设置该参数后,若用户发起建立连接请求,并完成了TCP的三次握手,内核也不会为了这次的连接调度worker进程来处理,只有用户真的发送请求数据时(内核已在网卡中收到请求数据包),内核才会唤醒worker进程处理这个连接。这个参数适用于大并发的情况,它减轻了worker进程的负担,当请求数据来临时,worker进程才会开始处理这个连接。 bind: 绑定当前端口/地址对,只有同时对一个端口监听多个地址时才会生效。 ssl: 在当前建立的端口上建立的连接必须基于ssl协议。
1 2 3 4 5 6 7 8 9 10 server_name server_name后可以跟多个主机名称,在处理一个http请求时,Nginx会取出header头中的Host,与每个server中的server_name进行匹配,以此决定到底由哪个server块来处理这个请求。匹配的优先级: 1.首先选择所有字符串完全匹配的server_name 2.其次选择通配符在前面的server_name 3.再次选择通配符在后面的server_name 4.最后选择使用正则表达式匹配的server_name,如~^\.test\.com$ 如果Host与所有的server_name都不匹配,这时将会按照下面的顺序处理server块: 1.优先选择在liten配置项后加入[default|default_server]的server块 2.找到匹配listen端口的第一个server块 如果server_name后面跟着空字符串(如server_name "";),那么表示匹配没有Host这个http头部的请求。
1 2 server_name_in_redirect 当打开时,表示在重定向请求时会使用server_name里配置的第一个主机名代替原先请求中的Host头部。
1 2 3 4 5 6 7 8 9 location 匹配规则: = 完全匹配 ~ 大小写敏感 ~* 忽略大小写 ^~ 表示只要前半部分匹配即可 @ 表示仅用于Nginx内部请求之间的重定向,带@的location不直接处理用户的请求,例如 error_page, try_files 优先级: = 高于 ^~ 高于 ~* 等于 ~ 高于 /
参数名
取值
默认值或示例
描述
root
path
/var/www/html
资源路径
alias
path
/var/www/html
资源路径
index
file…
/index.html /index.php
配置首页
error_page
[code] uri
404 /404.html
根据http返回码重定向页面
recursive_error_pages
[on|off]
off
是否允许递归使用error_page
try_files
path1 [path2…] uri
test.html
逐个尝试path
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 root和alias的区别 location /conf { root /usr/local/nginx; } location /conf { alias /usr/local/nginx; } 请求uri为/conf/nginx.conf 对于root会访问本地文件/usr/local/nginx/conf/nginx.conf 对于alias会访问本地文件/usr/local/nginx/nginx.conf alias支持添加正则表达式 location ~ ^/test/(\w+)\.(\w+)$ { alias /usr/local/nginx/$2/$1.$2; } 在访问/test/nginx.conf时,nginx会返回/usr/local/nginx/conf/nginx.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 error_page 当对某个请求返回错误码时,如果匹配上了error_page中设置的code,则重定向到新的uri中,例如: error_page 404 /404.html error_page 502 503 504 /50x.html error_page 403 http://example.com/forbidden.html error_page 404 = @fetch 重定向后,http错误和之前的相同,可通过"="来更改返回的错误码,例如: error_page 404 =200 /empty.gif 也可以根据重定向后的实际处理的结果设置错误码: error_page 404 = /empty.gif 重定向到其他location location / { error_page 404 @fallback; } location @fallback { proxy_pass http://backend; }
1 2 3 4 5 6 7 8 9 10 try_files try_files后要跟若干路径,如path1 path2,而且最后必须要有uri参数,该配置会顺序访问每个path,如果可以有效地读取,就直接返回这个path对应的文件结束请求,否则继续向下访问。如果所有的path都找不到有效的文件,就重定向到最后的参数uri上。因此,最后这个uri必须存在,而且它应该时可以有效重定向的。例如: try_files /system/maintenance.html $uri $uri/index.html $uri.html @other location @other { proxy_pass http://backend; } 也可通过错误码和error_page配合使用,例如: location / { try_files $uri $uri/ =404 }
参数名
取值
默认值或示例
描述
client_body_in_file_only
on|clean|off
off
HTTP包体只存储到磁盘文件中
client_body_in_single_buffer
on|off
off
HTTP包体尽量写入到一个内存buffer中
client_header_buffer_size
size
1k
存储HTTP头部的内存buffer大小
large_client_header_buffers
number size
4 8k
存储超大HTTP头部的内存buffer大小
client_body_buffer_size
size
8k/16k
存储HTTP包体的内存buffer大小
client_body_temp_path
dir-path
client_body_temp
HTTP包体的临时存放目录
connection_pool_size
size
256
连接池大小
request_pool_size
size
4k
请求内存池大小
1 2 client_body_in_single_buffer 用户请求中的HTTP包体一律存储到内存的buffer中,但是如果HTTP包体大小超过client_body_buffer_size设置的值,包体还是会写入到磁盘文件中
参数名
取值
默认值或示例
描述
client_header_timeout
time
60
读取HTTP头部的超时时间
client_body_timeout
time
60
读取HTTP包体的超时时间
send_timeout
time
60
发送响应的超时时间
reset_timeout_connection
on|off
off
发送RST包来直接重置连接
lingering_close
off|on|always
on
Nginx关闭用户连接的方式
lingering_time
time
30
lingering_timeout
time
5s
keepalive_disable
[msie6|safari|none]
msie6 safari
对某些浏览器禁用keepalive功能
keepalive
time
75
keepalive超时时间
keepalive_requests
num
100
keepalive连接上允许的最大请求数
tcp_nodelay
on|off
on
keepalive连接是否使用TCP_NODELAY选项
tcp_nopush
on|off
off
是否带TCP_CORK选项
1 2 reset_timeout_connection 这个选项打开后,Nginx会在某个连接超时后,不是使用正常的四次挥手关闭TCP连接,而是直接向用户发送RST重置包,不再等待用的应答。相比正常关闭的方式,它使得服务器避免产生许多处于FIN_WAIT_1,FIN_WAIT_2,TIME_WAIT状态的连接
1 2 3 4 5 6 7 8 9 lingering_close 该配置控制Nginx关闭用户连接的方式 always: 关闭用户连接前必须无条件地处理连接上所有用户发送的数据 off: 表示关闭连接时完全不管连接上是否已经有准备就绪的来着用户的数据 on: 中间值,一般情况下在关闭连接前都会处理连接上的用户数据,除了有些情况下在业务上认定这之后的数据是不必要的 lingering_close启用后,对上传大文件很有用,当用户请求的Content-Length大于max_client_body_size配置时,Nginx服务会立刻项用户返回413(Request entity too large)响应。但是,很多客户端可能不管413返回值,仍然持续不断地上传HTTP body,这时,经过lingering_time设置的时间后,Nginx将不管用户是否仍在上传,都会把连接关闭掉 在关闭连接前,会检测是否有用户发送的数据到达服务器,如果超过lingering_timeout时间后还没有数据可读,就会直接关闭连接;否则,必须在读取完连接缓冲区上的数据并丢弃掉后才会关闭连接
参数名
取值
默认值或示例
描述
types
…{…}
MIME type与文件扩展的映射
default_type
MIME-type
text/plain
当找不到映射时使用的默认MIME type
types_hash_bucket_size
size
32|64|128
查找MIME type散列表桶的大小
types_hash_max_size
size
1024
查找MIME type散列表桶的数量
参数名
取值
默认值或示例
描述
limit_except
… {…}
按HTTP方法名限制用户请求
client_max_body_size
size
1m
HTTP请求包体的最大值
limit_rate
speed
0
对请求的限速
limit_rate_after
time
1m
表示发送一定大小后再限速
1 2 3 4 5 6 limit_except limit_except GET { allow 192.168.1.0 /32 ; deny all; } 方法名取值包括:GET、HEAD、POST、PUT、DELETE、MKCOL、COPY、MOVE、OPTIONS、PROPFIND、PROPPATCH、LOCK、UNLOCK、PATCH等
参数名
取值
默认值或示例
描述
sendfile
on|off
off
sendfile系统调用
aio
on|off
off
AIO系统调用,与sendfile互斥
directio
size|off
off
是否使用O_DIRECT选项读取文件 对大文件读取速度有优化,与sendfile互斥
directio_alignment
size
512
directio读取文件时的对齐方式 通常512足够,对于高性能文件系统如 XFS文件系统可设置到4KB
open_file_cache
max=num [inactive=time] off
off
打开文件缓存,LRU算法淘汰
open_file_cache_errors
on|off
off
是否缓存打开文件的错误信息
open_file_cache_min_use
num
1
不被淘汰的最小访问次数
open_file_cache_valid
time
60s
检验缓存中元素有效性的频率
参数名
取值
默认值或示例
描述
ignore_invalid_headers
on|off
on
忽略不合法的HTTP头部
underscores_in_headers
on|off
off
HTTP头部是否允许下划线
if_modified_since
off|exact|before
exact
对If-Modified-Since头部的处理策略
log_not_found
on|off
on
文件未找到时是否记录到error日志
merge_slashes
on|off
on
是否合并相邻的”/“
resolver
address
8.8.8.8 114.114.114.114
设置DNS解析服务器地址
resolver_timeout
time
30s
DNS解析的超时时间
server_tokens
on|off
on
请求出错时是否在响应中标明Nginx版本
1 2 3 4 5 6 if_modified_since 出于性能考虑,Web浏览器一般会在客户端本地缓存一些文件,并存储当时获取的时间。这样下次向Web服务器获取缓存过的资源时,就可以用If-Modified-Since头部把上次获取的时间捎带上,而if_modified_since将根据后面的参数决定如何处理If-Modified-Since头部 相关参数说明: off: 忽略If-Modified-Since头部,正常返回文件内容,响应码200 exact: 当If-Modified-Since与文件的上次修改时间精准匹配时返回304(Not Modified),表示没有修改,浏览器直接读取缓存,否则正常返回文件内容,返回200 before: 当文件的上次修改时间比If-Modified-Since的时间早时返回304(Not Modified),表示没有修改,浏览器直接读取缓存,否则正常返回文件内容,返回200
在修改nginx配置文件和打日志的过程中可以带入一些变量,以下列出ngx_http_core_module模块提供的一些常用变量:
参数名
解释
$arg_PARAMETER
HTTP请求中某个参数的值,如/index.html?size=100,可以用$arg_size取得100这个值
$args
HTTP请求中的完整参数。例如,在请求/index.html?_w=120&_h=120中,$args表示字符串w=120&h=120
$binary_remote_addr
二进制格式的客户端地址。例如: \x0A\xE0B\x0E
$body_bytes_sent
表示在向客户端发送的http响应中,包体部分的字节数
$content_length
表示客户端请求头部中的Content-Length字段
$content_type
表示客户端请求头部中的Content-type字段
$cookie_COOKIE
表示在客户端请求头部中的的cookie字段
$document_root
表示当前请求所使用的root配置项的值
$uri
表示当前请求的URI,不带任何参数
$document_uri
与$uri含义相同
$request_uri
表示客户端发来的原始请求URI,带完整的参数。$uri和$document_uri未必是用户的原始请求,在内部重定向后可能是重定向后的URI,而$request_uri永远不会改变,始终是客户端的原始URI
$host
表示客户端请求头部中的Host字段,如果Host字段不存在,则以实际处理的server(虚拟主机)名称代替。如果Host字段中带有端口,如IP:PORT,那么$host是去掉端口的,它的值为IP。$host是全小写的。这些特性与http_HEADER中的http_host不同。http_host只是”忠实”地提取出Host头部对应的值
$hostname
表示Nginx所在机器的名称,与gethostbyname调用的返回值相同
$http_HEADER
表示当前HTTP请求中相应头部的值。HEADER名称全小写。例如,用$http_host表示请求中Host头部对应的值
$sent_http_HEADER
表示返回客户端的HTTP响应中相应头部的值。HEADER名称全小写。例如,用$sent_http_content_type表示响应中Content-Type头部对应的值
$is_args
表示请求中的URI是否带参数,如果带参数,$is_args值为?,如果不带参数,则是空字符串
$limit_rate
表示当前连接的限速是多少,0表示无限速
$nginx_version
表示当前Nginx的版本号,如1.0.14
$query_string
请求URI中的参数,与$args相同,然后$query_string是只读的不会改变
$remote_addr
表示客户端的地址
$remote_port
表示客户端连接使用的端口
$remote_user
表示使用Auth Basic Module时定义的用户名
$request_filename
表示用户请求中URI经过root或alias转换后的文件路径
$request_body
表示HTTP请求中的包体,该参数只在proxy_pass或fastcgi_pass中有意义
$request_body_file
表示HTTP请求中包体存储的临时文件名
$request_completion
当请求已经全部完成时,其值为”ok”。若没有完成,就要返回客户端,则其值为空字符串;或者在断点续传等情况下使用HTTP range访问的并不是文件的最后一块,那么其值也是空字符串
$request_method
表示HTTP请求的方法名,如GET、PUT、POST等
$scheme
表示HTTP scheme,如在请求https://nginx.org 中表示https
$server_addr
表示服务器地址
$server_name
表示服务器名称
$server_port
表示服务器端口
$server_protocol
表示服务器向客户端发送响应的协议,如HTTP/1.1或HTTP/1.0
Linux网络参数调优 由于默认的 Linux内核参数考虑的是最通用的场景,这明显不符合用于支持高并发访问的Web服务器的定义,所以需要修改 Linux内核参数,使得 Nginx可以拥有更高的性能。
在优化内核时,可以做的事情很多,不过,我们通常会根据业务特点来进行调整,当Nginx作为静态Web内容服务器、反向代理服务器或是提供图片缩略图功能(实时压缩图片)的服务器时,其内核参数的调整都是不同的。这里只针对最通用的、使 Nginx支持更多并发请求的TCP网络参数做简单说明。
首先,需要修改/etc/sysctl. conf来更改内核参数。例如,最常用的配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 fs.file-max = 999999 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_keepalive_time = 600 net.ipv4.tcp_fin_timeout = 30 net.ipv4.tcp_max_tw_buckets = 5000 net.ipv4.ip_local_port_range = 1024 61000 net.ipv4.tcp_rmem = 4096 32768 262142 net.ipv4.tcp_wmem =4096 32768 262142 net.core.netdev_max_backlog = 8096 net.core.rmem_default = 262144 net.core.wmem_default = 262144 net.core.rmem_max = 2097152 net.core.wmem_max = 2097152 net.ipv4.tcp_syncookies = 1 net.ipv4.tcp_max_syn.backlog = 1024
然后执行 sysctl -p命令,使上述修改生效。