##################################################################################################################
# main全局配置 #
##################################################################################################################
user www www; #默认为nobody
# 设置nginx工作进程的用户
worker_processes 2; # 默认为1
# 设置worker角色的工作进程的个数,正常情况下可以设置成cpu的内核数,最多设置为8个;
# 也可以将worker_processes的值设为auto,这样nginx会自动检测CPU核数并打开相同数量的worker进程;
# 当nginx添加了SSL证书时,最好要打开多个worker进程。SSL握手会进行硬盘I/O操作。所以打开多个worker进程有利于性能的提升;
worker_cpu_affinity 01 10;
# 通过设置cpu粘性来降低由于多CPU核切换造成的寄存器等现场重建带来的性能损耗,上述设置表示第一个worker进程用第一个cpu,第二个worker进程进程使用第二个cpu
worker_rlimit_nofile; # 默认为操作系统的限制(65535)
# 设置每个worker进程的最大打开文件数(句柄)限制
error_log logs/error.log error;
# 配置错误日志路径以及打印级别(debug | info | notice | warn | error | crit | alert | emerg)
# 生产场景一般是warn | error | crit 这三个级别之一,级别太低会有太多IO消耗,影响效率
pid logs/nginx.pid;
# pid文件为文本文件,内容只有一行, 记录了该进程的ID,根据PID文件的内容,准确判断进程是否正在运行,防止意外启动多个进程实例。
# 只有获得pid文件(固定路径固定文件名)写入权限(F_WRLCK)的进程才能正常启动并把自身的PID写入该文件中,其它同一个程序的多余进程则自动退出。
##################################################################################################################
# events模块中包含nginx中所有处理连接的设置 #
##################################################################################################################
events {
use epoll;
# 用于设置处理客户端请求的轮询方法
# 在Linux操作系统下,nginx默认使用epoll事件模型
# 同时Nginx在OpenBSD或FreeBSD操作系统上采用类似于epoll的高效事件模型kqueue
# 在操作系统不支持这些高效模型时才使用select
worker_connections 2048; #默认为512
# 设置可由一个worker进程同时打开的最大连接数。但不能超过worker_rlimit_nofile的设置
accept_mutex on; # 默认为on
# 当一个新连接到达时,如果激活了accept_mutex,那么多个Worker将以串行方式来处理,其中有一个Worker会被唤醒,其他的Worker继续保持休眠状态;
# 如果没有激活accept_mutex,那么所有的Worker都会被唤醒,不过只有一个Worker能获取新连接,其它的Worker会重新进入休眠状态,[thundering herd现象](https://en.wikipedia.org/wiki/Thundering_herd_problem)
accept_mutex_delay 500ms; # 默认为500ms
# 当accept_mutex功能启用后,只有一个持有mutex锁的worker进程会接受并处理请求,其他worker进程等待。accept_mutex_delay指定的时间就是这些worker进程的等待时间,过了等待时间下一个worker进程便取得mutex锁,处理请求。
multi_accept on # 默认为off
# multi_accept可以让nginx worker进程尽可能多地接受请求,提高性能
# 如果设置为on,可以让worker进程一次性地接受监听队列里的所有请求,然后处理
# 如果multi_accept的值设为off,那么worker进程必须一个一个地接受监听队列里的请求
# 如果web服务器面对的是一个持续的请求流,那么启用multi_accept可能会造成worker进程一次接受的请求大于worker_connections指定可以接受的请求数。这就是overflow,这个overflow会造成性能损失,overflow这部分的请求不会受到处理
}
##################################################################################################################
# 提供http服务相关的一些配置参数 #
##################################################################################################################
http {
####################################################################################
# 基本配置 #
####################################################################################
include mime.types;
# include可以包含若干子配置文件,实现不同需求配置独立,可以将不同的server配置在不同的conf文件里
# mime.types文件列出针对不同的请求文件返回的HTTP response的Content-Type的Accept值
# 除非服务端Web程序手动设置了Content-Type,如果Web程序没设置,则会从mime.types中匹配返回
# 如果mime.types中也没找到对应文件的扩展名的话,就使用默认的default_type
default_type application/octet-stream;
# 如果在mime.types的配置中没有找到响应请求文件的格式,则走default_type
types_hash_max_size 2048;
# 设置散列表的冲突率。
# types_hash_max_size越大,就会消耗更多的内存,但散列key的冲突率会降低,检索速度就更快。
# types_hash_max_size越小,消耗的内存就越小,但散列key的冲突率可能上升。
server_tokens off;
# 返回错误页面时是否在Server中注明Nginx版本
server_names_hash_bucket_size 64;
# 为了提高快速寻找到相应server_name的能力,Nginx 使用散列表来存储server_name,server_names_hash_bucket_size设置了每个散列桶占用的内存大小。
server_name_in_redirect off;
# 重定向主机名称的处理.该配置需要配合server_name使用.
# 设置为on时,表示在重定向请求时会使用stream里配置的第一个主机名代替原先请求中的Host头部,而当关闭时,表示在重定向请求时使用请求本身的Host头部。
####################################################################################
# 日志配置 #
####################################################################################
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# 定义日志nginx日志文件的打印格式并命名为变量main
access_log logs/access.log main;
# access_log指定nginx的访问日志的存放路径文件以及使用的日志文件格式
#access_log off;
# 为了提高效率,可以将访问日志关掉
access_log /data/logs/nginx-access.log buffer=32k flush=5s;
# buffer和flush可以设置缓存日志的刷盘策略,日志超过32k才刷盘,如果没满32k,但是超过5s也自动刷盘
rewrite_log on; # 默认是off
# 开启或者关闭rewrite模块指令执行的日志,如果开启,则重写将记录下notice等级的日志到nginx 的error_log中
####################################################################################
# 高效文件传输 #
####################################################################################
sendfile on;
# 当一个程序需要传输文件时,Linux内核首先将文件数据缓冲,然后将文件数据传送给程序缓冲,最后程序将文件数据传输到目的地。
# Sendfile方法是一种数据传输的更高效的方法,数据在内核中的文件描述符之间传输
# 这种方法的结果是改善了对操作系统资源的利用,提高Nginx静态资源托管效率,直接在内核空间完成文件发送,不需要先read再write,没有上下文切换开销
tcp_nopush on;
# TCP_NOPUSH是FreeBSD的一个socket选项,对应Linux的TCP_CORK,Nginx里统一用tcp_nopush来控制它,并且只有在启用了sendfile之后才生效。
# 启用它之后,数据包会累计到一定大小之后才会发送,减小了额外开销,提高网络效率
tcp_nodelay on;
# TCP_NODELAY也是一个socket选项,启用后会禁用Nagle算法,尽快发送数据,某些情况下可以节约200ms
# Nagle算法原理是:在发出去的数据还未被确认之前,新生成的小数据先存起来,凑满一个 MSS 或者等到收到确认后再发送
# Nginx 只会针对处于keep-alive状态的TCP连接才会启用tcp_nodelay
keepalive_timeout 65;
# 一个keepalive连接在闲置超过一定时间后(默认的是75秒),会主动关闭这个长连接
# 客户端可以设置http服务要不要走长连接,通过设置请求头Connection=keep-alive实现的,http1.0默认是关闭的,http1.1默认是打开的
# 谷歌浏览器同时最多有6个tcp连接
# keepalive_timeout时间不能设置太长,因为太长会长时间占用tcp连接不释放,导致服务器的tcp连接不够用;也不能太短,如果太短会导致一些大文件上传接口因为上传一半而中断;
keepalive_requests 200;
# 设置同一个长连接上最多请求次数,超过这个次数,将主动关闭这个长连接
####################################################################################
# http_proxy 设置,client相关配置 #
####################################################################################
client_max_body_size 10m;
# 允许客户端请求的最大单文件字节数限制。如果有上传较大文件的需求,尽量设置大一些
client_body_buffer_size 128k;
# 缓冲区代理用户端请求的最大字节数
client_header_timeout 60;
# 指定等待client发送一个请求头的超时时间,仅当在一次read中,没有收到请求头,才会算成超时。如果在超时时间内,client没发送任何东西,nginx返回HTTP状态码408(“Request timed out”)
client_body_timeout 60;
# 该指令设置请求体(request body)的读超时时间。仅当在一次readstep中,没有得到请求体,就会设为超时。超时后,nginx返回HTTP状态码408(“Request timed out”)
####################################################################################
# http_proxy 设置,server相关配置 #
####################################################################################
proxy_connect_timeout 60;
# 该指令设置与upstream server的连接超时时间,有必要记住,这个超时不能超过75秒
proxy_send_timeout 75;
# 这个指定设置了发送请求给upstream服务器的超时时间。超时设置不是为了整个发送期间,而是在两次write操作期间。如果超时后,upstream没有收到新的数据,nginx会关闭连接
proxy_read_timeout 75;
# 该指令设置与代理服务器的读超时时间。它决定了nginx会等待多长时间来获得请求的响应。这个时间不是获得整个response的时间,而是两次reading操作的时间,默认值60s
proxy_upstream_fail_timeout 10;
# Upstream模块下server指令的参数,设置了某一个upstream后端失败了指定次数(max_fails)后,该后端不可操作的时间,默认为10秒
proxy_buffer_size 4k;
# 设置代理服务器(nginx)从后端realserver读取并保存用户头信息的缓冲区大小,默认与proxy_buffers大小相同,其实可以将这个指令值设的小一点
proxy_buffers 4 32k;
# proxy_buffers缓冲区,4个缓存,每个大小限制为32k。
proxy_busy_buffers_size 64k;
# 高负荷下缓冲大小(proxy_buffers*2)
proxy_temp_file_write_size 64k; # 默认为1024M
# 当proxy_buffers放不下后端服务器的响应内容时,会将一部分保存到硬盘的临时文件中,这个值用来设置最大临时文件大小,默认1024M
# 它与proxy_cache没有关系,大于这个值,将从upstream服务器传回。设置为0禁用
proxy_temp_path /usr/local/nginx/proxy_temp 1 2;
# 指定缓存写到那个目录
####################################################################################
# gzip压缩功能设置 #
####################################################################################
gzip on;
# 开启gzip压缩输出,减少网络传输,客户端通过设置请求头Accept-Encoding=gzip, deflate, br来支持gzip压缩
gzip_static on;
# nginx对于静态文件的处理模块,该模块可以读取预先压缩的gz文件,这样可以减少每次请求进行gzip压缩的CPU资源消耗。
# 该模块启用后,nginx首先检查是否存在请求静态文件的gz结尾的文件,如果有则直接返回该gz文件内容
gzip_disable "msie[1-6].";
# IE6的某些版本对gzip的压缩支持很不好,会造成页面的假死,为了确保其它的IE6版本不出问题,所以建议加上gzip_disable的设置
gzip_min_length 1k;
# 设置允许压缩的页面最小字节数,页面字节数从header头得content-length中进行获取。默认值是20。建议设置成大于1k的字节数,小于1k可能会越压越大
gzip_buffers 4 16k;
# 设置系统获取几个单位的缓存用于存储gzip的压缩结果数据流。4 16k代表以16k为单位,安装原始数据大小以16k为单位的4倍申请内存
gzip_http_version 1.0;
# 用于识别http协议的版本,早期的浏览器不支持Gzip压缩,用户就会看到乱码,所以为了支持前期版本加上了这个选项。
# 如果你用了Nginx的反向代理并期望也启用Gzip压缩的话,由于末端通信是 http/1.0,故请设置为 1.0
gzip_comp_level 6;
# gzip压缩比,1压缩比最小处理速度最快,9压缩比最大但处理速度最慢(传输快但比较消耗cpu)
gzip_types text/html text/plain text/css text/javascript application/json application/javascript application/x-javascript
application/xml;
# 匹配mime类型进行压缩,无论是否指定,”text/html”类型总是会被压缩的
gzip_vary on;
# 和http头有关系,会在响应头加个Vary:Accept-Encoding,可以让前端的缓存服务器缓存经过gzip压缩的页面,例如,用Squid缓存经过Nginx压缩的数据
gzip_proxied any
# Nginx作为反向代理的时候启用,决定开启或者关闭后端服务器返回的结果是否压缩,匹配的前提是后端服务器必须要返回包含”Via”的 header头
##################################################################################
# FastCGI 设置,为了保证Nginx下PHP环境的高速稳定运行,需要添加一些FastCGI优化指令 #
##################################################################################
fastcgi_cache_path /usr/local/nginx/fastcgi_cache levels=1:2 keys_zone=TEST:10m inactive=5m;
# 为FastCGI缓存指定一个文件路径、目录结构等级、关键字区域存储时间和非活动删除时间
fastcgi_connect_timeout 300;
# 指定连接到后端FastCGI的超时时间
fastcgi_send_timeout 300;
# 指定向FastCGI传送请求的超时时间,这个值是已经完成两次握手后向FastCGI传送请求的超时时间
fastcgi_read_timeout 300;
# 指定接收FastCGI应答的超时时间,这个值是已经完成两次握手后接收FastCGI应答的超时时间
fastcgi_buffer_size 64k;
# 用于指定读取FastCGI应答第一部分需要多大的缓冲区,这个值表示将使用1个64KB的缓冲区读取应答的第一部分(应答头),可以设置为fastcgi_buffers选项指定的缓冲区大小
fastcgi_buffers 4 64k;
# 指定本地需要用多少和多大的缓冲区来缓冲FastCGI的应答请求。
# 如果一个PHP脚本所产生的页面大小为256KB,那么会为其分配4个64KB的缓冲区来缓存;如果页面大小大于256KB,那么大于256KB的部分会缓存到fastcgi_temp指定的路径中。
# 一般这个值应该为站点中PHP脚本所产生的页面大小的中间值,如果站点大部分脚本所产生的页面大小为256KB,那么可以把这个值设置为“16 16k”、“4 64k”等
fastcgi_temp_file_write_size 128k;
# 表示在写入缓存文件时使用多大的数据块,默认值是fastcgi_buffers的两倍
fastcgi_cache TEST;
# 表示开启FastCGI缓存并为其指定一个名称。开启缓存非常有用,可以有效降低CPU的负载,并且防止502错误的发生
fastcgi_cache_valid 200 302 1h;
# 指定code为200,302的响应缓存为一小时
fastcgi_cache_valid 301 1d;
# 指定code为301的缓存有效时间为1天
fastcgi_cache_valid any 1m;
# 其它缓存有效时间都为1分钟
##################################################################################
# 设定负载均衡后台服务器列表 #
##################################################################################
upstream backend {
keepalive 30
# 在开启长连接的情况下,最多保持空闲长连接的个数,如果超过这个数量,最近最少使用的长连接将被关闭
ip_hash; # 默认为round-robin
# 负载均衡处理方式,一共有三种方式:
# (1)round-robin(轮训请求方式)
# (2)ip_hash(回话持久化方式,这个方法保证从同一个客户端发起的请求总是定向到同一台服务器)
# (3)least_conn(最少连接方式,找连接最少的服务进行处理)
server 192.168.10.100:8080 max_fails=2 fail_timeout=30s weight=2;
server 192.168.10.101:8080 max_fails=2 fail_timeout=30s weight=3;
server 192.168.10.101:8080 backup
server 192.168.10.101:8080 down;
# weight设置每个服务的命中几率,默认是1;
# backup表示备份服务,只有所有的非备份不能使用时,会启动该服务,down表示当前服务永远不参与负载;
# max_fails表示容许请求失败的次数,当超过该次数时将暂停一定时间(fail_timeout)
}
##################################################################################
# server虚拟主机配置 #
##################################################################################
server {
############################################
# 基本配置 #
############################################
listen 80 default_server; # 默认为80
# 监听端口设置,小于1024的要以root启动,
# default_server表示如果找不到对应端口的server_name,则默认走这个匹配
server_name itoatest.example.com;
# 一个nginx可以配置多个server,nginx通过检查请求header中host来匹配每个server的server_name决定走哪个server,
# 如果没有任何一个server可以匹配,则会选择第一个server做匹配。默认匹配可以通过listen中添加defalut_server来改变。
# server_name有四种匹配方式:
# (1)精确匹配(itoatest.example.com)
# (2)星号开头的最长的通配符名称(*.example.org)
# (3)星号结束的最长的通配符名称(mail.*)
# (4)正则表达式匹配(~^www\d+\.example\.net$,正则表达式必须以~开头)
root /apps/oaapp;
# 见下文location讲解
allow 223.252.218.196;
allow 59.111.28.48/32;
# allow表示允许某个ip或ip段访问
deny all
# deny表示禁止某个ip或者ip段访问
error_page 500 502 503 504 /50x.html;
error_page 403 http://example.com/forbidden.html;
# 这个参数可以为错误代码指定相应的错误页面
charset utf-8;
# 设置http头信息的charset编码
if ($request_method = POST) {
return 405;
}
# 关于if的使用请看下文[Nginx中如何使用变量?]
############################################
# location特定的URL对应的一系列配置项 #
############################################
location /i/ { # 关于location中的路径匹配规则以及匹配优先级请看下文[Nginx中location部分URL如何匹配?]
root /apps/oaapp;
#alias /apps/oaapp/;
# root和alias都可以用来指定请求资源的真实路径。
# 区别是root最后得到的资源地址是root的值加上location的值,而alias正如其名,alias指定的路径是location的别名,不管location的值怎么写,资源的真实路径都是 alias 指定的路径。
# 比如当访问http://itoatest.example.com/i/hello.gif这个地址时,如果是root,资源的真实路径是/apps/oaapp/i/hello.gif;如果是alias真实路径是/apps/oaapp/hello.gif;
# alias只能作用在location中,而root可以存在server、http和location中
# alias 后面必须要用 “/” 结束,否则会找不到文件,而 root 则对 ”/” 可有可无
index index.jsp index.html index.htm;
# 当用户请求的是http://itoatest.example.com/i/这个地址时,就会自动在root配置指令指定的文件系统目录下依次寻找 index.jsp 和 index.html,index.htm这三个文件,直到找到一个并返回
autoindex on; # 默认为off
# 当index指定的文件都找不到时,如果开启autoindex,那么则会生成一个root所指目录下的“目录索引”的html并返回,如果没有开启,则会返回forbidden
autoindex_exact_size off # 默认为on
# 只有在autoindex开启时才起作用,默认为on,显示出文件的确切大小,单位是bytes。改为off后,显示出文件的大概大小,单位是kB或者MB或者GB
autoindex_localtime on # 默认为off
# 只有在autoindex开启时才起作用,默认为off,显示的文件时间为GMT时间。改为on后,显示的文件时间为文件的服务器时间
proxy_pass http://backend;
# 请求转向某个upstream定义的负载均衡的服务器列表,如果只有一台服务器的话,也可以直接写成proxy_pass http://ip:port;
rewrite ^/i/(.*) /$1 break;
# rewrite 的作用是修改 $uri,具体细节请看下文[rewrite如何重写url?]
proxy_redirect off; # 默认是default
proxy_redirect http://192.168.10.101:8080/i/wuman/ http://itoatest.example.com/i/wuman/
# 如果需要修改从被代理服务器传来的应答头中的"Location"和"Refresh"字段,可以用这个指令设置,分为三种情况:
#(1)proxy_redirect off表示不修改服务端的redirect地址
#(2)proxy_redirect default 将根据location和proxy_pass的设置来决定
#(3)可以自己设置不同的替换规则
proxy_set_header Host $host; #默认是$proxy_host
# 可以通过三个变量对Host进行设置:
#(1)$proxy_host,表示是反向代理后的host,就是proxy_pass后面跟的host
# (2) $host首先从请求头中获取Host值,如果没有则选择server_name
# (3) $http_host是直接从请求头中获取,所以可能为空,如果是非80/443端口的时候,$http_host = $host:$port
proxy_set_header X-Real-IP $remote_addr;
# 由于在客户端和web服务器之间增加了中间层,因此web服务器无法直接拿到客户端的ip,通过$remote_addr变量拿到的将是反向代理服务器的ip地址;
# 所以我们可以设置一个请求头X-Real-IP,通过获取这个请求头就可以拿到客户端的真实ip
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 上述的意思增加一个$proxy_add_x_forwarded_for到X-Forwarded-For里去,注意是增加,而不是覆盖
# 如果每次代理都使用上述配置,那么X-Forwarded-For可以获取到经过多次代理后的客户多IP以及多层代理nginx的IP:IP0, IP1, IP2...
# 所以proxy_set_header也是获取真实客户端ip的一种方法
proxy_set_header X-Forwarded-Proto https;
# 请求标头可帮助您识别客户端与您的负载均衡器连接时所用的协议,并随后将标题传递到您的服务器
proxy_set_header X-Forwarded-Host $host
# 可以帮助您识别客户端与您的负载均衡器连接时所用的host,并随后将标题传递到您的服务器
proxy_set_header X-Forwarded-Host $port
# 可以帮助您识别客户端与您的负载均衡器连接时所用的port,并随后将标题传递到您的服务器
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; # 默认是error timeout
# 指定在什么情况下将请求应传递到下一个服务器,如果设置为off表示在任何情况下都不需要传递
# error表示发生错误时,将请求传递到下一个服务器
# timeout表示发生请求或者响应超时时,将请求传递给下一个服务器
# invalid_header表示服务器返回空响应或无效响应时,将请求传递给下一个服务器
# http_code表示服务器返回对应的code时将请求传递到下一个服务器
proxy_next_upstream_timeout 30 # 默认是0
# 限制请求可以传递到下一个服务器的时间,0表示关闭限制
proxy_next_upstream_tries 2 # 默认为0
# 限制将请求传递到下一个服务器的可能尝试次数, 0值关闭此限制
}
location ~ .*\.(gif|jpg|jpeg|bmp|png|ico|txt|js|css)$
{
root /apps/oaapp;
expires 7d;
# 对于站点中不经常修改的静态内容(如图片,JS,CSS),可以在服务器中设置expires过期时间,控制浏览器缓存,达到有效减小带宽流量,降低服务器压力的目的
}
location = /50x.html {
root html;
}
location = /video {
directio 4m; # 该路径下所有大于4M的文件不直接从磁盘读取,不走缓存
# Direct I/O是文件系统的一个功能,它允许程序绕过内核缓存,直接在硬盘上读写数据
# 这可以充分利用CPU频数,改善缓存的有效性,Directo I/O适用于访问率少的数据。这些数据不需要缓存在任何位置
# 在http, server和location当中都可以定义
# 如果某个请求是通过directo I/O,那么这个请求不能使用sendfile功能
}
}
}