静态web服务器主要功能由ngx_http_core_module模块实现。
虚拟主机与请求分发
监听端口
listen address:port [ default(deprecated in 0.8.21) | default_server | [backlog = num | rcvbuf = size | sndbuf = size | accept_filter = filter | deferred | bind | ipv6only = [ on | off] | ssl] ]
默认: listen 80
配置块:server
listen参数决定Nginx服务如何监听端口,listen可以之家IP,端口或主机名
- backlog
表示TCP中backlog队列的大小,默认为-1表示不设置。TCP建立三次握手过程中,进程还没有开始处理监听句柄,这是backlog队列将会放置这些新连接,如果backlog队列已满,还有新的客户端建立连接就会失败。
- rcvbuf
设置监听句柄的SO_RCVBUF参数
- sndbuf
设置监听句柄的SO_SNDBUF参数
- accept_filter
设置accept过滤器
- deferred
设置后,在完成TCP握手,内核也不会调度worker进程来处理,只有用户发送请求了才会唤醒worker进程处理这个连接。
这个参数适用于大并发情况,减轻worker进程的负担
- bind
绑定当前端口,只有同时对一个端口监听多个地址时才会生效
- ssl
当前监听的端口上建立的连接必须基于SSL协议
主机名称
server_name name […];
默认:server_name ””
配置块:server
server_name后可以跟多个主机,在开始处理一个HTTP请求时,Nginx会取出header头中的HOST,与每个server中的server_name进行匹配,决定用哪一个server块来处理。
有可能一个HOST能匹配多个server。server_name与HOST匹配优先级如下:
- 首先选择所有字符串完全匹配的server_name,如:abc.test.com
- 其次选择通配符在前面的server_name,如:*.test.com
- 再次选择通配符在后面的server_name,如:abc.test.*
- 最后选择使用正则表达式才匹配的server_name,如:~^.test.com$
如果都没有匹配时,
- 优先选择listen配置项加入default | default_server 的server块
- 找到listen端口的第一个server块
如果server_name后面跟着空字符串,则表示匹配没有host的请求
server_names_hash_bucket_size
server_names_hash_bucket_size size;
默认:server_names_hash_bucket_size 32|64|128;
配置块:http,server,location
为了提高找到相应的server_name的速度,Nginx使用散列表来存储server_name,此参数设置散列桶占用的内存大小
server_names_hash_max_size
server_names_hash_max_size size;
server_names_hash_max_size 512;
配置块:http,server,location
参数影响散列表的冲突率,
server_names_hash_max_size 越大,消耗内存越多,散列key冲突率降低,检索速度更快。
server_names_hash_max_size 越小,消耗内存越小,散列key冲突率增高,检索速度更慢。
重定向主机名称的处理
server_name_in_redirect on |off
默认:server_name_in_redirect on;
配置块:http,server,location
配合server_name使用,on打开时,表示在重定向请求时会使用server_name里配置第一个主机名代替原先请求中的host头
location
location [=||*|^~|@] /uri/ {…}
配置块:server
匹配方式
- =表示URI完全匹配
- ~表示匹配时大小写敏感
- ~*表示匹配URI时忽略大小写
- ^~表示匹配URI时只需要其前半部分与uri参数匹配即可
- @ 表示仅用于Nginx服务内部请求之间的重定向
注意:location是有序的,当一个请求有可能匹配到多个location时,实际上这个请求会被第一个location处理
文件路径的定义
- 以root方式设置资源路径
root path;
默认:root html;
配置块:http,server,location,if
location /a {
root /usr/local/html
}
则在请求/a/index/demo.html时,会返回/usr/local/html/a/index/demo.html文件内容
- 以alias 方式设置资源路径
alias path;
配置块:location
location /conf {
alias /usr/local/conf;
}
等价于
location /conf {
root/usr/local;
}
location ~ ^/test/(\w+)\.(\w+)$ {
alias /usr/local/nginx/$2/$1.$2;
}
则访问/test/nginx.conf时,会获取/usr/local/nginx/conf/nginx.conf
- 访问首页
index file …;
默认:index index.html;
配置块:http,server,location
location / {
root path;
index /index.html /html/index.php /index.php;
}
在接收到请求先访问path/index.php ,如果可以访问则直接返回,如果访问不了,则访问path/html/index.php依次类推
结论:index写在最后的优先访问
- 根据HTTP返回码重定向页面
error_page code
配置块:http,server,location,if
error_page 404 /404.html;
error_page 502 503 504 /50x.html;
error_page 403 http://demo/index.html;
error_page 404 =@fetch;
虽然重定向了,但是返回的状态码不会变化
error_page 404 =200 /demo.png;
设置等于,可以修改返回的状态码
error_page 404 = /demo.png;
设置等于,后面不写状态码则会根据重定向后实际的结果显示状态码
如果不想修改uri,只想项把请求重定向到另一个location进行处理,如下设置,返回404的状态码会被反向代理到backend上有服务器中处理
location / {
error_page 404 @fallback;
}
location @fallback {
proxy_pass http://backend;
}
- 是否允许递归使用error_page
recursive_error_pages [on | off]
默认:recursive_error_pages off;
配置块:http,server,location
确定是否允许递归地定义error_page
内存以及磁盘资源分配
- HTTP包体只存储到自盘文件中
client_body_in_file_only on | clean | off;
默认:client_body_in_file_only off;
配置块:http,server,location
值为非off时,用户请求的HTTP请求包体一律存储到磁盘文件中,即使为0kb也会存储为文件。
如果设置为on,当请求结束时,文件不会删除,用于调式,定位问题
如果设置为clean,则会删除该文件
- HTTP包体尽量写入到一个内存buffer中
client_body_in_single_buffer on | off;
默认:client_body_in_single_buffer off;
配置块:http,server,location
用户请求的HTTP包体一律存储到内存buffer中,当包体大小大于client_body_buffer_size时,包体还是会写入磁盘
- 存储HTTP头部的内存buffer大小
client_header_buffer_size size;
默认:client_header_buffer_size 1k;
配置块:http,server
nginx接收请求中header部分(HTTP行和HTTP头部)时分配的内存buffer大小,如果(请求行+请求头)大于这个,large_client_header_buffers才会生效
- 存储超大HTTP 头部的内存buffer大小
large_client_header_buffers number size;
默认:large_client_header_buffers 4 8k;
配置块:http,server
设置接收一个超大HTTP头部请求的buffer个数和每个buffer的大小。
如果请求行的大小超过设置的单个buffer大小8k,则会返回Request URI too large 414
请求中一般会有许多header,每个header(例如:Authorization=2233444)的大小也不饿能超过单个buffer大小,否则返回Bad request 400
请求行和请求头部的总和也不可以超过buffer个数乘以buffer大小(4 * 4k = 16k)
请求行:请求方法+请求URL+协议以及版本号
请求头:header头
- 存储HTTP包体的内存buffer大小
client_body_buffer_size size;
默认:client_body_buffer_size 8k/16k
配置块:http,server,location
定义Nginx接收HTTP包体的内存缓冲区大小,包体先接收到指定的缓冲区,之后才决定是否写入磁盘
注意:如果请求中包含HTTP头部Content-Length,并且其标识的长度小于定义的buffer大小,则Nginx会自动降低本次请求所使用的buffer内存,降低内存消耗
- HTTP包体的临时存放目录
client_body_temp_path dir-path [ level1 [ level2 [ level3 ] ] ]
默认:client_body_temp_path client_body_temp;
配置块:http,server,location
定义HTTP包体存放的临时目录,接收到HTTP包体时,如果包体大小大于client_body_buffer_size ,则会以一个递增的整数命名并存放到client_body_temp_path 指定的目录中。
为了防止一个目录下文件过多,所以设置level参数,可以最多加三层目录
例如:client_body_temp_path /opt/nginx/client_temp 1 2;
如果上传的HTTP包体使用00000123456作为临时文件,会被存放到 /opt/nginx/client_temp/6/45中
- connection_pool_size
connection_pool_size size;
默认:connection_pool_size 256;
配置块:http,server
Nginx对于每个建立成功的TCP连接会预先分配一个内存池,上面的为内存池的初始大小,用于减少内核对于小块内存的分配次数。
更大的size会消耗内存增多,更小的
- request_pool_size
request_pool_size size;
默认:request_pool_size 4k;
配置块:http,server
Nginx开始处理HTTP请求时,会为每个请求分配一个内存池,size执行初始化内存池的大小,用于减少内核对于小块内存的分配次数。
TCP连接关闭时,会销毁connection_pool_size指定的连接内存池
HTTP请求结束时,会销毁request_pool_size指定的HTTP连接池。
但是他们创建销毁事件不一样,一个TCP连接可能被复用于多个HTTP请求
网络连接的设置
- 读取HTTP头部的超时时间
client_header_timeout time(默认单位:s)
默认:client_header_timeout 60
配置块:http,server,location
客户端服务器建立连接后开始接收HTTP头部,超过,则返回408(Request timed out)响应
- 读取HTTP包体的超时时间
client_body_timeout time (默认单位:s)
默认:client_body_timeout 60;
配置块:http,server,location
- 发送的超时时间
send_timeout time;
默认: send_timeout 60;
配置块:http,server,location
发送响应的超时时间,即Nginx服务器向客户端发送了数据包,但是客户端一直没有接收这个数据包,超过这个时间会关闭这个连接
- reset_timeout_connection
reset_timeout_connection on | off
默认:reset_timeout_connection off;
配置块:http,server,location
连接超时后通过向客户端发送RST包来直接重置连接。
如果开启,在连接超时后,不是使用正常情形的四次握手关闭TCP连接,而是直接向用户发送RST重置包,不再等待用户的应答,直接释放Nginx服务器上关于这个套接字的所有缓存
相比正常关闭,避免产生许多处于FIN_WAIT_1,FIN_WAIT_2,TIME_WAIT状态的TCP连接
- lingering_close
lingering_close on | off | always
默认:lingering_close on;
配置块:http,server,location
配置Nginx关闭用户连接的方式。
always:关闭用户连接前必须无条件的处理连接上所有用户发送的数据
off:关闭连接完全不管连接上时候已经有准备就绪的来自用户的数据
on:中间值,在关闭连接前都会处理连接上的用户发送的数据,除了有些情况业务上认定这之后的数据是不必要的
- lingering_time
lingering_close time;
默认:lingering_close 30s;
配置块:http,server,location
lingering_close启用后,这个配置对于上传大文件很有用。
当body大于max_client_body_size配置时,则会返回413(Request entity too large)响应。
但是很多客户端不管413返回值,持续不断上传HTTP body,这是经过lingering_time时间后,Nginx会不管用户是否在上传,都会关闭连接
- lingering_timeout
lingering_timeout time;
默认:lingering_timeout 5s;
配置块:http,server,location
lingering_close生效后,在关闭连接前,会检测是否有用户发送数据,如果超过lingering_timeout还没有数据可读,就直接关闭连接。
否则在读取完连接缓冲区上的数据并丢掉后才关闭连接
- 对某些浏览器禁用keepalive功能
keepalive_disable [ msie6 | safari | none]
默认:keepalive_disable msie6 safari
配置块:http,server,location
某些浏览器对于使用keepalive功能的POST请求处理有功能性问题,需要禁用IE6以及早期版本,Safari浏览器
- keepalive超时时间
keepalive_timeout time(单位:s)
默认:keepalive_timeout 75;
配置块:http,server,location
一个keepalive连接闲置超过一定时间后,都会关闭这个连接。
- 一个keepalive长连接上允许承载的请求最大数
keepalive_requests n;
默认:keepalive_requests 100;
配置块:http,server,location
一个keepalive连接上默认最多只能发送100个请求
- tcp_nodelay
tcp_nodelay on | off
默认:tcp_nodelay on
配置块:http,server,location
确定对keepalive连接是否使用TCP_NODELAY选项
- tcp_nopush
tcp_nopush on | off
默认:tcp_nopush off;
配置块:http,server,location
在打开sendfile选项时,确定是否开启FreeBSD系统上的TCP_NOPUSH或Linux系统上的TCP_CORK功能。
打开tcp_nopush后,将会发送响应时把整个响应报头放到一个TCP包中发送
MIME类型设置
- MIME type与文件扩展的映射
type {…};
配置块:http,server,location
定义MIME type到文件扩展名的映射,多个扩展名可以映射到同一个MIME type
types {
text/html html;
text/html conf;
image/gif gif;
image/jpeg jpg;
}
- 默认MIME type
default_type MIME-type
默认:default_type text/plain;
配置块:http,server,location
当找不到对应的MIME type与文件扩展名之间的映射时,使用默认的MIME type作为HTTP header中的 Content-Type
- types_hash_bucket_size
types_hash_bucket_size size;
默认:types_hash_bucket_size 32|64|128;
配置块:http,server,location
为了快速找到相应MIME type,Nginx使用散列表来存储MIME type与文件扩展名。
types_hash_bucket_size设置了每个散列桶占用的内存大小
- type_hash_max_size
type_hash_max_size size;
默认:type_hash_max_size 1024;
配置块:http,server,location
type_hash_max_size影响散列表的冲突率。
type_hash_max_size越大,会消耗更多的内存,但散列key的冲突率会降低,检索速度更快;
type_hash_max_size越小,消耗内存小,散列key冲突率可能上升
对客户端请求的限制
- 按HTTP方法名限制用户请求
limit_except methoe … {…};
配置块:location
Nginx通过limit_except后面指定的方法名来限制用户请求。方法名可取值包括:GET,HEAD,POST,PUT,DELETE,MKCOL,COPY,MOVE,OPTIONS,PROPFIND,PROPPATCH,LOCK,UNLOCK,PATCH。
limit_except GET {
allow 192.168.1.0/32;
deny all;
}
注意:允许GET意味着允许HEAD方法,上面是意思是禁止GET和HEAD方法,其他HTTP方法是允许的
- HTTP请求包体的最大值
client_max_body_size size;
默认:client_max_body_size 1m;
配置块:http,server,location
浏览器发送较大HTTP包体时,头部会携带Content-Length字段,client_max_body_size用来限制Content-Length大小。
不用等Nginx接收完所有的HTTP包体,才告诉不就收请求。
发现Content-Length超过client_max_body_size值时,就直接发送413(”Request Entity Too Large“)响应给客户端
- 对请求的限速
limit_rate speed;
默认:limit_rate 0;
配置块:http,server,location
对客户端请求限制每秒传输的字节数,默认为0表示不限制,单位可以是k,K,m,M
server {
if($slow){
set $limit_rate 4k;
}
}
- limit_rate_after
limit_rate_after time;
默认:limit_rate_after 1m;
配置块:http,server,location
表示nginx向客户端发送的响应长度超过limit_rate_after后才开始限速
limit_rate_after 1m;
limit_rate 100k;
文件操作的优化
- sendfile系统调用
sendfile on | off
默认:sendfile off;
配置块:http,server,location
可以启动lInux上的sendfile系统调用来发送文件,减少了内核态与用户态之间的两次内存复制,这样从磁盘读取文件后直接在内核态发送到网卡设备,提高了发送文件的效率
- AIO系统调用
aio on | off
默认:aio off;
配置块:http,server,location
表示是否在FreeBSD或linux系统上启用内核级别的异步文件IO功能,与senffile是互斥的
- directio
directio size | off;
默认:directio off;
配置块:http,server,location
在FreeBSD和linux系统上使用O_DIRECT选项取读取文件,缓冲区大小为size,通常对大文件的读取速度有优化作用。与sendfile互斥
- directio_alignment
directio_alignment size;
默认:directio_alignment 512;
配置块:http,server,location
对客户端请求的特殊处理
- 忽略不合法的HTTP头部
ignore_invalid_headers on | off;
默认:ignore_invalid_headers on;
配置块:http,server
如果设置为off,当出现不合法的HTTP头,Nginx会拒绝服务,并直接返回400(Bad Request)错误。
如果设置为on,则忽略此HTTP头部
- HTTP头部是否允许下划线
underscores_in_headers on | off
默认:underscores_in_headers off;
配置块:http,server
默认为off,表示HTTP头部的名称不允许带下划线
- 对If-Modified-Since头部的处理策略
If-Modified-Since [off | exact | before]
默认:If-Modified-Since exact
配置块:http,server,location
出于性能考虑,一般客户端会缓存文件,并存储当时获取的时间。下次向web服务器获取缓存过的资源时,就可以用If-Modified-Since头部把上次的带上
当值为off时:忽略If-Modified-Since头,或者这个文件,直接返回,HTTP响应码为200
当值为exact时:对比If-Modified-Since与要返回的文件上次修改时间,没有精确匹配上,则返回200和文件内容。如果匹配上,则表示浏览器就是最新的,会返回304 Not Modified,不会返回文件内容来浪费带宽,浏览器收到响应后会直接读取本地的缓存
当值为before时:比exact宽松,只要文件上次修改时间等于或早于用户请求中的If-Modified-Since,就会返回304 Not Modified
- 文件未找到时是否记录到error日志
log_not_found on | off
默认:log_not_found on;
配置块:http,server,location
表示当处理用户请求时且需要访问文件时,如果没有找到文件,是否将错误日志记录到error.log文件中,只是用于定位问题
- merge_slashes
merge_slashes on | off;
默认:merge_slashes on;
配置块:http,server,lcoation
表示是否合并相邻的”/“ ,例如://test///a.txt 配置为on时,匹配为location /test/a.txt ;如果配置为off,则不会匹配,URI依然是//test///a.txt
- DNS解析地址
resolver address …;
配置块:http,server,location
resolver 127.0.0.1 192.0.0.1;
- DNS解析的超时时间
resolver_timeout time;
默认:resolver_timeout 30s;
配置块:http,server,location
表示DNS解析的超时时间
- 返回错误页面是否在Server中注明Nginx版本
server_tokens on | off
默认:server_tokenson;
配置块:http,server,location
表示处理请求出错时,是否在响应的Server头部表明Nginx版本,方便定位问题
ngx_http_core_module模块提供的变量
在记录access.log访问日志时,可以使用ngx_http_core_module模块处理请求时所产生的变量,这些变量也可以用于其他HTTP模块。
变量 | 变量描述 |
---|---|
$arg_patameter | HTTP请求中某个参数的值,如/index.html?size=100,可以用$arg_size取得100这个值 |
$args | HTTP请求中的完整参数,如/index.html?size=100&_t=10,则$args表示字符串size=100&_t=10 |
$binary_remote_addr | 二进制格式的客户端地址。例如:\x0A\xE0B\x0E |
$body_bytes_sent | 表示在想客户端发送的http响应中,包体部分的字节数 |
$content_length | 表示客户端请求头部中Conten-Length字段 |
$conten_type | 表示客户端请求头部中Conten-Type字段 |
$cookie_COOKIE | 表示客户端请求头部中cookie字段 |
$document_root | 表示当前请求所使用的root配置项的值 |
$uri | 表示当前请求的URI,不带任何参数 |
$document_uri | 与$uri相同 |
$request_uri | 表示客户端发来的原始请求URI,带完整的参数。 u r i 和 uri和 uri和document_uri未必是用户的原始请求,在内部重定向后可能是重定向的URI,而$request_uri永远不会改变,时钟是客户端的原始URI |
$host | 表示客户端请求头部中的Host字段,如果Host字段不存在,则以实际处理的server名称代替,如果Host字段中带有端口,如IP:PORT,那么 h o s t 是去掉端口的,它的值是 I P , host是去掉端口的,它的值是IP, host是去掉端口的,它的值是IP,host是全小写 |
$hostname | 表示Nginx所在机器的名称 |
$http_HREADER | 表示当前HTTP请求中相应头部的值。HEADER名称全小写。例如:$http_host表示请求中Host头部对应的值 |
$sent_http_HERDER | 表示返回客户端的HTTP响应中相应头部的值。HEADER名称全小写。例如:$sent_http_content_type表示响应中的content_type头部对应的值 |
$is_args | 表示请求中的URI是否携带参数,如果携带值为?,如果没有为空字符串 |
$limit_rate | 表示当前连接的限速是多少,0表示无限速 |
$nginx_version | 表示当前Nginx的版本号,如1.0.14 |
$query_string | 请求URI中的参数,与 a r g s 相同,但是 args相同,但是 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_completion | 当请求全部完成时,其值为ok,如果没有完成,返回客户端,其值为空字符串 |
$request_method | 表示HTTP请求中的方法名,GET、PUT、POST等 |
$scheme | 表示HTTP scheme,如在请求https://nginx.com中表示https |
$server_addr | 表示服务器地址 |
$server_name | 表示服务器名称 |
$server_port | 表示服务器端口 |
$server_protocol | 表示服务器向客户端发送响应的协议,例如HTTP/1.1或HTTP/1.0 |