先介绍一下 nginx.conf 文件的结构
- main块设置的指令将影响其他所有设置;
- server块的指令主要用于指定主机和端口;
- upstream指令主要用于负载均衡,设置一系列的后端服务器;
- location块用于匹配网页位置。
这是来自 Nginx官方网站 的一个例子。
可以先熟悉一下 文件结构,具体配置是干嘛的,下面会讲。
user username usergroup;
worker_processes 2;
pid /var/run/nginx.pid;
# [ debug | info | notice | warn | error | crit ]
error_log /var/log/nginx.error_log info;
events {
worker_connections 2000;
# use [ kqueue | epoll | /dev/poll | select | poll ];
use kqueue;
}
http {
include conf/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$gzip_ratio"';
log_format download '$remote_addr - $remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$http_range" "$sent_http_content_range"';
client_header_timeout 3m;
client_body_timeout 3m;
send_timeout 3m;
client_header_buffer_size 1k;
large_client_header_buffers 4 4k;
gzip on;
gzip_min_length 1100;
gzip_buffers 4 8k;
gzip_types text/plain;
output_buffers 1 32k;
postpone_output 1460;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
send_lowat 12000;
keepalive_timeout 75 20;
#lingering_time 30;
#lingering_timeout 10;
#reset_timedout_connection on;
server {
listen one.example.com;
server_name one.example.com www.one.example.com;
access_log /var/log/nginx.access_log main;
location / {
proxy_pass http://127.0.0.1/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 10m;
client_body_buffer_size 128k;
client_body_temp_path /var/nginx/client_body_temp;
proxy_connect_timeout 70;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_send_lowat 12000;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
proxy_temp_path /var/nginx/proxy_temp;
charset koi8-r;
}
error_page 404 /404.html;
location = /404.html {
root /spool/www;
}
location /old_stuff/ {
rewrite ^/old_stuff/(.*)$ /new_stuff/$1 permanent;
}
location /download/ {
valid_referers none blocked server_names *.example.com;
if ($invalid_referer) {
#rewrite ^/ http://www.example.com/;
return 403;
}
#rewrite_log on;
# rewrite /download/*/mp3/*.any_ext to /download/*/mp3/*.mp3
rewrite ^/(download/.*)/mp3/(.*)\..*$
/$1/mp3/$2.mp3 break;
root /spool/www;
#autoindex on;
access_log /var/log/nginx-download.access_log download;
}
location ~* \.(jpg|jpeg|gif)$ {
root /spool/www;
access_log off;
expires 30d;
}
}
}
配置文件各部分详解
main
user username usergroup;
worker_processes 2;
pid /var/run/nginx.pid;
# [ debug | info | notice | warn | error | crit ]
error_log /var/log/nginx.error_log info;
worker_rlimit_nofile 65535
- user username usergroup;
user是个主模块指令,指定Nginx Worker进程运行以及用户组。默认是 nobody 。 - worker_processes
Nginx要开启的 worker 进程数。每个Nginx进程平均耗费10M~12M内存。建议指定和CPU的数量一致即可。查看你的linux服务器CPU数量top 然后 按 1
这里可以设置成具体的数字,也可以设置成 auto 。auto Nginx进程会自动检测你的服务器CPU数量。 - error_log
错误日志输出路径,可以指定日志输出级别,debug 输出日志最详细。 - pid
指定进程 pid 的存储文件位置。如果不指定,则默认置于路径 logs/nginx.pid。 - worker_rlimit_nofile
指定进程可以打开的最多文件描述数目,理论值应该是最多打开文件数(ulimit -n )与nginx进程数相除,但是Nginx分配请求并不是那么均匀,所以最好与ulimit -n 的值保持一致。
现在在Linux2.6 内核下开启文件打开数为65535,worker_rlimit_nofile 就相应应该填写65535.这是因为Nginx调度时请求到进程并不是那么均衡,所以假如填写10240,总并发量达到3-4万时就有进程超过10240了,这就会返回502。
events
events {
# use [ kqueue | epoll | /dev/poll | select | poll ];
use epoll;
worker_connections 2000;
}
- use
use是事件模块指令,用来指定nginx的工作模式。可选项 select、poll、kqueue、epoll、rtsig和/dev/poll 。其中select 和poll 都是标准的工作模式,kqueue和epoll是高效的工作模式,不同的是epoll用在Linux平台上,而kqueue用在BSD系统中。对于Linux系统,epoll工作模式是首选。 - worker_connections
worker_connections是事件模块指令,用来指定nginx进程的最大连接数,默认是1024.
http
http {
include conf/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$gzip_ratio"';
log_format download '$remote_addr - $remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$http_range" "$sent_http_content_range"';
- include conf/mime.types;
定义MIMI-Type
这里需要讲一下 include 指令,主要用于将其他的Nginx配置或第三方模块的配置引用到当前的主配文件中,减少主配置文件的复杂度。
如果你的服务器上运行多个项目及端口。每一个都在主配文件中配置,会非常多,混乱。这时候,你只需要将每个项目分离出去,写各自项目的nginx配置文件,最后在主配文件中 include 你的配置文件 即可。
我在 nginx + uwsgi 搭建 Django web 服务 采用了这种方式。 - default_type
属于HTTP核心模块指令,这里设定默认类型为二进制流。也就是当文件类型未定义时使用这种方式。 - log_format
是Nginx的HttpLog模块指令,用于指定Nginx日志的输出日志。具体可以参考 HttpLog模块
client_header_timeout 3m;
client_body_timeout 3m;
send_timeout 3m;
client_header_buffer_size 1k;
large_client_header_buffers 32k;
- client_header_timeout
设置客户端请求头读取超时时间。如果超过这个时间,客户端还没有发送任何数据,Nginx将返回“Request time out(408)”错误; - client_body_timeout
设置客户端请求主体读取超时时间。如果超过这个时间,客户端还没有发送任何数据,Nginx将返回“Request time out(408)”错误,默认值是60; - send_timeout
指定响应客户端的超时时间。这个超时仅限于两个连接活动之间的时间,如果超过这个时间,客户端没有任何活动,Nginx将会关闭连接。 - client_max_body_size
用来设置允许客户端请求的最大的单个文件字节数; - client_header_buffer_size
用于指定来自客户端请求头的headerbuffer大小。对于大多数请求,1K的缓冲区大小已经足够,如果自定义了消息头或有更大的Cookie,可以增加缓冲区大小。这里设置为32K
gzip on;
gzip_min_length 1100;
gzip_buffers 4 8k;
gzip_types text/plain;
- gzip
Nginx的HttpGzip模块。这个模块支持在线实时压缩输出数据流。
需要自行安装,查看是否安装gzip模块。已安装的 会有configure arguments: --with-http_stub_status_module --with-http_gzip_static_module --prefix=/opt/nginx
类似这样的输出。我这里是没有的,我在这里没有安装,我就不安装了。
- gzip
用于设置开启或者关闭gzip模块,“gzip on”表示开启GZIP压缩,实时压缩输出数据流; - gzip_min_length
设置允许压缩的页面最小字节数,页面字节数从header头的Content-Length中获取。默认值是0,不管页面多大都进行压缩。建议设置成大于1K的字节数,小于1K可能会越压越大; - gzip_buffers
表示申请4个单位为16K的内存作为压缩结果流缓存,默认值是申请与原始数据大小相同的内存空间来存储gzip压缩结果; - gzip_http_version
用于设置识别HTTP协议版本,默认是1.1,目前大部分浏览器已经支持GZIP解压,使用默认即可; - gzip_comp_level
用来指定GZIP压缩比,1 压缩比最小,处理速度最快;9 压缩比最大,传输速度快,但处理最慢,也比较消耗cpu资源; - gzip_types
用来指定压缩的类型,无论是否指定,“text/html”类型总是会被压缩的; - gzip_vary
选项可以让前端的缓存服务器缓存经过GZIP压缩的页面,例如用Squid缓存经过Nginx压缩的数据。
output_buffers 132k;
postpone_output 1460;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
send_lowat 12000;
keepalive_timeout 60;
- output_buffers
设置从磁盘读取缓冲区响应的数量和大小。如果可能,客户端数据传输将被延迟,直到 Nginx 汇集到适合的数据大小。 - postpone_output
- sendfile tcp_nopush tcp_nodelay
sendfile 参数用于开启高效文件传输模式。将tcp_nopush和tcp_nodelay两个指令设置为on用于防止网络阻塞; - send_lowat
- keepalive_timeout
置客户端连接保持活动的超时时间。在超过这个时间之后,服务器会关闭该连接;
upstream
upstream ProjectName{
ip_hash;
server 192.168.8.11:80;
server 192.168.8.12:80 down;
server 192.168.8.13:8009 max_fails=3 fail_timeout=20s;
server 192.168.8.146:8080;
}
upstream是Nginx的HTTP Upstream模块,这个模块通过一个简单的调度算法来实现客户端IP到后端服务器的负载均衡。
在上面的设定中,通过upstream指令指定了一个负载均衡器的名称ProjectName。这个名称可以任意指定,在后面需要的地方直接调用即可。
Nginx的负载均衡模块目前支持4种调度算法,其中后两项属于第三方的调度方法。
- 轮询(默认):每个请求按时间顺序逐一分配到不同的后端服务器,如果后端某台服务器宕机,故障系统被自动剔除,使用户访问不受影响;
- Weight:指定轮询权值,Weight值越大,分配到的访问机率越高,主要用于后端每个服务器性能不均的情况下;
- ip_hash:每个请求按访问IP的hash结果分配,这样来自同一个IP的访客固定访问一个后端服务器,有效解决了动态网页存在的session共享问题;
- fair:比上面两个更加智能的负载均衡算法。此种算法可以依据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配。Nginx本身是不支持fair的,如果需要使用这种调度算法,必须下载Nginx的upstream_fair模块;
- url_hash:按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,可以进一步提高后端缓存服务器的效率。Nginx本身是不支持url_hash的,如果需要使用这种调度算法,必须安装Nginx 的hash软件包。
在HTTP Upstream模块中,可以通过server指令指定后端服务器的IP地址和端口,同时还可以设定每个后端服务器在负载均衡调度中的状态。常用的状态有:
- down:表示当前的server暂时不参与负载均衡;
- backup:预留的备份机器。当其他所有的非backup机器出现故障或者忙的时候,才会请求backup机器,因此这台机器的压力最轻;
- max_fails:允许请求失败的次数,默认为1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误;
- fail_timeout:在经历了max_fails次失败后,暂停服务的时间。max_fails可以和fail_timeout一起使用。
注意,当负载调度算法为ip_hash时,后端服务器在负载均衡调度中的状态不能是weight和backup。
server
建议将对虚拟主机进行配置的内容写进另外一个文件,然后通过include指令包含进来,这样更便于维护和管理。
server {
listen one.example.com;
server_name 123.4.5.7 www.one.example.com;
index index.html;
root /wwwroot/www.baidu.com
charset gb2312;
access_log /var/log/nginx.access_log main;
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
- listen
用于指定虚拟主机的服务端口, - server_name
用来指定IP地址或域名,多个域名之间用空格分开。 - index
用于设定访问的默认首页地址.。 - root
指令用于指定虚拟主机的网页根目录,这个目录可以是相对路径,也可以是绝对路径。 - charset
用于设置网页的默认编码格式。 - access_log
用来指定虚拟主机的访问日志存放路径,最后的main 用于指定访问日志的输出格式。 - error_page
设置了虚拟主机的错误信息返回页面,通过error_page指令可以定制各种错误信息的返回页面。在默认情况下,Nginx会在主目录的html目录中查找指定的返回页面,特别需要注意的是,这些错误信息的返回页面大小一定要超过512K,否者会被ie浏览器替换为ie默认的错误页面。
location
URL地址匹配是进行Nginx配置中最灵活的部分。 location支持正则表达式匹配,也支持条件判断匹配,用户可以通过location指令实现Nginx对动、静态网页进行过滤处理。使用location URL匹配配置还可以实现反向代理,用于实现PHP动态解析或者负载负载均衡。
location ~* \.(jpg|jpeg|gif)$ {
root /spool/www;
access_log off;
expires 30d;
}
- 所有扩展名以.gif、.jpg、.jpeg、.png、.bmp、.swf结尾的静态文件都交给nginx处理,而expires用来指定静态文件的过期时间,这里是30天。
location ~ ^/(upload|html)/ {
root /web/wwwroot/www.baidu.com;
expires 30d;
}
- 将upload和html下的所有文件都交给nginx来处理,当然,upload和html目录包含在/web/wwwroot/www.baidu.com目录中。
location ~ .*.php$ {
index index.php;
proxy_pass http://localhost:8080;
}
- location是对此虚拟主机下动态网页的过滤处理,也就是将所有以.jsp为后缀的文件都交给本机的8080端口处理。
反向代理相关配置
location / {
proxy_pass http://127.0.0.1:8000/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 10m;
client_body_buffer_size 128k;
client_body_temp_path /var/nginx/client_body_temp;
proxy_connect_timeout 70;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_send_lowat 12000;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
proxy_temp_path /var/nginx/proxy_temp;
charset koi8-r;
}