Fork me on GitHub

nginx配置与优化

Nginx作为一个非常流行和成熟的Web Server和Reserve Proxy Server,网上有大量的性能优化教程,但是不同的业务场景千差万别,什么配置是最适合自己的,还是只有基于自己的业务才能配置出适合自己的参数。

nginx的安装

自动安装


这里我们可以直接配置好官方yum源,直接yum安装即可
1
2
3
4
5
6
7
8
vim /etc/yum.repos.d/nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/6/$basearch/
gpgcheck=0
enabled=1
# 确认yum源无误后直接yum安装即可
yum -y install nginx

编译安装


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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# 检查和安装依赖项(gcc、正则表达式工具、传送内容压缩的zlib库、openssl开启https支持),-y表示静默安装
yum -y install gcc pcre pcre-devel zlib zlib-devel openssl openssl-devel
# 下载源码包
wget http://nginx.org/download/nginx-1.8.0.tar.gz
# 解压源码包
tar zxvf nginx-1.8.0.tar.gz
# 进入解压的目录配置相关参数(可以使用--help查看可选项)
cd nginx-1.8.0/
./configure \
true--prefix=/usr/local #安装路径
true--sbin-path=/usr/sbin/nginx #程序文件安装路径
true--conf-path=/etc/nginx/nginx.conf #主配置文件安装路径
true--error-log-path=/var/log/nginx/error.log #错误日志文件的路径
true--http-log-path=/var/log/nginx/access.log #访问日志文件的路径
true--pid-path=/var/run/nginx.pid #pid文件的路径
true--lock-path=/var/run/nginx.lock #锁文件的路径
true--http-client-body-temp-path=/var/cache/nginx/client_temp #客户端body部分临时文件存放路径
true--http-proxy-temp-path=/var/cache/nginx/proxy_temp
true--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp
true--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp
true--http-scgi-temp-path=/var/cache/nginx/scgi_temp
true--user=nginx #以nginx属主运行worker进程
true--group=nginx #以nginx属组运行worker进程
true--with-http_ssl_module #SSL模块,需安装OPENSSL
true--with-http_realip_module
true--with-http_addition_module
true--with-http_sub_module
true--with-http_dav_module
true--with-http_flv_module #启用ngx_http_flv模块
true--with-http_mp4_module
true--with-http_gunzip_module
true--with-http_gzip_static_module #启用需要依赖zlib
true--with-http_random_index_module
true--with-http_secure_link_module
true--with-http_stub_status_module #启用server status页面
true--with-http_auth_request_module
true--with-threads
true--with-stream
true--with-stream_ssl_module
true--with-http_slice_module
true--with-file-aio
true--with-http_v2_module
true--with-debug #打开调试机制
# 安装
make && make install
# 启动和关闭nginx
cd /opt/nginx/sbin/
./nginx
ps -aux|grep nginx # 查看进程(正常工作的时候有守护进程和工作进程)
./nginx -h # 查看帮助

nginx的配置


nginx的主配置文件位于安装目录下的conf/nginx.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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# 指明worker的进程数;通常应该为CPU的核心数减1
worker_processes 7;
# event指令与事件模型有关,配置处理连接有关信息
events {
# 单个worker进程所能够并发打开的最大连接数;默认为1024
# 当前主机能响应最大并发连接数:worker_processes * worker_connections
worker_connections 1024;
}
# http指令处理http请求
http {
# mime type映射
include mime.types;
default_type application/octet-stream;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
# server 表示一个虚拟主机,一台服务器可配置多个虚拟主机
server {
# 监听端口
listen 80;
# 识别的域名
server_name localhost;
# 一个关键设置,与url参数乱码问题有关
charset utf-8;
#access_log logs/host.access.log main;
#location表达式:
#syntax: location [=|~|~*|^~|@] /uri/ { … }
#分为两种匹配模式,普通字符串匹配,正则匹配
#无开头引导字符或以=开头表示普通字符串匹配
#以~或~* 开头表示正则匹配,~*表示不区分大小写
#多个location时匹配规则
#总体是先普通后正则原则,只识别URI部分,例如请求为/test/1/abc.do?arg=xxx
#1. 先查找是否有=开头的精确匹配,即location = /test/1/abc.do {...}
#2. 再查找普通匹配,以 最大前缀 为规则,如有以下两个location
# location /test/ {...}
# location /test/1/ {...}
# 则匹配后一项
#3. 匹配到一个普通格式后,搜索并未结束,而是暂存当前结果,并继续再搜索正则模式
#4. 在所有正则模式location中找到第一个匹配项后,以此匹配项为最终结果
# 所以正则匹配项匹配规则受定义前后顺序影响,但普通匹配不会
#5. 如果未找到正则匹配项,则以3中缓存的结果为最终结果
#6. 如果一个匹配都没有,返回404
#location =/ {...} 与 location / {...} 的差别
#前一个是精确匹配,只响应/请求,所有/xxx类请求不会以前缀匹配形式匹配到它
#而后一个正相反,所有请求必然都是以/开头,所以没有其它匹配结果时一定会执行到它
#location ^~ / {...} ^~意思是非正则,表示匹配到此模式后不再继续正则搜索
#所有如果这样配置,相当于关闭了正则匹配功能
#因为一个请求在普通匹配规则下没得到其它普通匹配结果时,最终匹配到这里
#而这个^~指令又相当于不允许正则,相当于匹配到此为止
location / {
root html; # 网站根目录,默认是安装目录下的html目录(可以指定绝对路径)
index index.html index.htm;
# deny all; 拒绝请求,返回403
# allow all; 允许请求
}
location /test/ {
deny all;
}
location ~ /test/.+\.jsp$ {
# proxy_pass表示代理
proxy_pass http://192.168.132.144:8080;
}
location ~ \.jsp$ {
proxy_pass http://192.168.132.144:8080;
}
# 定义各类错误页
error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# @类似于变量定义
# error_page 403 http://www.jikexueyuan.com这种定义不允许,所以利用@实现
error_page 403 @page403;
location @page403 {
proxy_pass http://http://www.jikexueyuan.com;
}
}
# another virtual host using mix of IP-, name-, and port-based configuration
server {
listen 80;
#listen 9090
server_name www.test.com test.com other.cc;
location / {
# root d:\\test; 注意,win下d:\test因转义符问题不允许
root d:/test
index index.html index.htm;
}
}
}

nginx的优化


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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# nginx不同于apache服务器,当进行了大量优化设置后会魔术般的明显性能提升效果
# nginx在安装完成后,大部分参数就已经是最优化了,我们需要管理的东西并不多
#user nginx;
# 阻塞和非阻塞网络模型:
# 同步阻塞模型,一请求一进(线)程,当进(线)程增加到一定程度后
# 更多CPU时间浪费到切换一,性能急剧下降,所以负载率不高
# Nginx基于事件的非阻塞多路复用(epoll或kquene)模型
# 一个进程在短时间内可以响应大量的请求
# 建议值 <= cpu核心数量,一般高于cpu数量不会带好处,也许还有进程切换开销的负面影响
worker_processes 4;
# 将work process绑定到特定cpu上(核心数量与数字位数对应,进程数量与数字的组数对应),避免进程在cpu间切换的开销
worker_cpu_affinity 0001 0010 0100 1000
# 8内核4进程时的设置方法 worker_cpu_affinity 00000001 00000010 00000100 10000000
# 每进程最大可打开文件描述符数量(linux上文件描述符比较广义,网络端口、设备、磁盘文件都是)
# 文件描述符用完了,新的连接会被拒绝,产生502类错误
# linux最大可打开文件数可通过ulimit -n FILECNT或 /etc/security/limits.conf配置
# 理论值 系统最大数量 / 进程数。但进程间工作量并不是平均分配的,所以可以设置的大一些
worker_rlimit_nofile 655350
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
# 并发响应能力的关键配置值
# 每个进程允许的最大同时连接数,work_connectins * worker_processes = maxConnection;
# 要注意maxConnections不等同于可响应的用户数量,
# 因为一般一个浏览器会同时开两条连接,如果反向代理,nginx到后端服务器的连接也要占用连接数
# 所以,做静态服务器时,一般 maxClient = work_connectins * worker_processes / 2
# 做反向代理服务器时 maxClient = work_connectins * worker_processes / 4
# 这个值理论上越大越好,但最多可承受多少请求与配件和网络相关,也可最大可打开文件,最大可用sockets数量(约64K)有关
worker_connections 500;
true
# 指明使用epoll 或 kquene (*BSD)
use epoll
# 备注:要达到超高负载下最好的网络响应能力,还有必要优化与网络相关的linux内核参数
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
# 关闭此项可减少IO开销,但也无法记录访问信息,不利用业务分析,一般运维情况不建议使用
access_log off
true
# 只记录更为严重的错误日志,可减少IO压力
error_log logs/error.log crit;
#access_log logs/access.log main;
true
# 启用内核复制模式,应该保持开启达到最快IO效率
sendfile on;
true
# 简单说,启动如下两项配置,会在数据包达到一定大小后再发送数据
# 这样会减少网络通信次数,降低阻塞概率,但也会影响响应及时性
# 比较适合于文件下载这类的大数据包通信场景
#tcp_nopush on; 在
#tcp_nodelay on|off on禁用Nagle算法
true
#keepalive_timeout 0;
# HTTP1.1支持持久连接alive
# 降低每个连接的alive时间可在一定程度上提高可响应连接数量,所以一般可适当降低此值
keepalive_timeout 30s;
true
true#隐藏nginx版本号
trueserver_tokens off;
true
# 启动内容压缩,有效降低网络流量
gzip on;
true
# 过短的内容压缩效果不佳,压缩过程还会浪费系统资源
gzip_min_length 1000;
true
# 可选值1~9,压缩级别越高压缩率越高,但对系统性能要求越高
gzip_comp_level 4;
true
# 压缩的内容类别
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
true# 静态文件缓存
# 最大缓存数量,文件未使用存活期
open_file_cache max=655350 inactive=20s;
true
# 验证缓存有效期时间间隔
open_file_cache_valid 30s;
true
# 有效期内文件最少使用次数
open_file_cache_min_uses 2;
true
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}

nginx的常用模块

ngx_http_stub_status_module模块


此模块用来显示nginx访问的一些重要信息
基本配置
1
2
3
4
5
6
location /nginx_status {
stub_status on;
access_log off;
allow SOME.IP.ADD.RESS;
deny all;
}

重启nginx之后直接在网页输入http://IP/nginx_status 即可
返回结果类似于:

1
2
3
4
Active connections: 1
server accepts handled requests
155 155 298
Reading: 0 Writing: 1 Waiting: 0

Active connections: 处于活动状态的客户端连接的数量;
accepts:已经接受的客户端连接的总数;
handled:已经处理完成的客户端请求的总数;
requests:客户端发来的总的请求数;
Reading:处于读取客户端请求报文首部的连接数;
Writing:处于向客户端发送响应报文过程中的连接数;
Waiting:处于等待客户端发出请求的空闲连接数;

ngx_http_gzip_module模块


此模块用来压缩页面资源
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
gzip on|off;
#启用或禁用压缩gzip响应报文
gzip_comp_level level;
#指定压缩比(1->9),默认为1
gzip_disable regex...;
#regex是匹配客户端浏览器类型的模式,表示对所有匹配到的浏览器不执行压缩
gzip_min_length length;
#触发启用压缩功能的响应报文的最小长度(启用压缩的下限)
gzip_http_version 1.0|1.1 ;
#设定启用压缩响应功能时,协议的最小版本
gzip_types mime-type;
#指定仅执行压缩的资源内容类型,默认为text/html;
gzip proxied off|expired|no-cache|no-store|private|no_last_modified|no_etag|auth|ant...;
#对代理的请求基于何种属性判断其是否应该启用压缩功能

配置示例:

1
2
3
4
5
6
gzip on;
gzip_http_version 1.0;
gzip_comp_level 6;
gzip_disable msie6;
gzip_min_length 2;
gzip_types text/plain text/css text/xml application/x-javascript application/xml application/json application/java-script;

ngx_http_ssl_module模块


此模块主要用来配置https
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
ssl on|off;
#是否启用ssl应用
ssl_certificate file;
#当前虚拟主机使用的PEM格式的证书文件
ssk_certificate_key file;
#当前虚拟主机使用证书文件的私钥文件
ssl_protocols [SSLv3][TLSv1][TLSv1.1][TLSv1.2]
#当前ssl的协议版本
ssl_session_cache off|none|[builtin[:size]][shared:name:size];
#指明ssl会话的缓存机制
trueoff 坚决被禁止使用会话
truenone 有可能会禁止
truebuiltin 使用openssl内建的库缓存机制,此为各worker独有的
truetrue缺陷:同一个用户请求第一次可能会被调度到第一个worker,第二次可能会被调度到第二个worker,可能会导致缓存无法命中
trueshared 由各worker共享的缓存
truename 缓存空间的名称
truesize 字节为单位的缓存空间的大小,每1MB内存空间可缓存4000个会话
ssl_clphers clphers;
#指明ssl的加密算法
ssl_session_timeout time;
#ssl会话超时时长,至ssl session cache中缓存条目的超时时长

配置示例:

1
2
3
4
5
6
server {
listen 443;
ssl on;
ssl_certificate /usr/local/nginx/conf/server.crt;
ssl_certificate_key /usr/local/nginx/conf/server_nopwd.key;
}

ngx_http_referer_module模块


此模块用于屏蔽的网站请求无效值的字段,可以用来防盗链
1
2
3
4
5
6
7
8
9
10
valid_referers none | blocked | server_names | string ...;
#定义合法的referer数据;
truenone:请求报文首部没有refe rer首部;
trueblocked:请求报文的referer首部没有值;
trueserver_names:其值是主机名;
truearbitrary string:直接字符串,可以使用*作为通配符;
trueregular expression:被指定的正则表达式模式匹配到的字符串;要使用~起始;
true
$invalid_referer变量是由ngx_http_referer_module模块自动引入的
#只要不能被valid_referers none blocked...匹配到的,统统被归类到变量$invalid_referer中

配置示例:

1
2
3
4
5
valid_referers none blocked server_names *.magedu.com magedu.* ~\.magedu\.;
if ($invalid_referer) {
truereturn 403;
}

ngx_http_rewrite_module模块


此模块主要用于url重写操作
last:重写完成后停止对当前uri在当前locatuion中的后续操作,改为对新uri的新一轮处理
break:重写完成后停止对当前uri在当前location中的后续其他重写操作
redirect: 重写完成后以永久重定向方式直接返回重写后生成的新URL给客户端,由客户对新URL进行请求(302)
permanent:重写完成后以永久重定向方式直接返回重写后生成的新URL给客户端,由客户对新URL进行请求(301)
配置示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
if ($http_user_agent ~ MSIE) {
rewrite ^(.*)$ /msie/$1 break;
}
if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
set $id $1;
}
if ($request_method = POST) {
return 405;
}
if ($slow) {
limit_rate 10k;
}
if ($invalid_referer) {
return 403;
}

ngx_http_fastcgi_module模块


此模块主要用于基于fastcgi通信

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
31
32
33
34
35
36
37
38
fastcgi_connect_timeout 300;
#指定链接到后端FastCGI的超时时间。
fastcgi_send_timeout 300;
#向FastCGI传送请求的超时时间,这个值是指已经完成两次握手后向FastCGI传送请求的超时时间。
fastcgi_read_timeout 300;
#指定接收FastCGI应答的超时时间,这个值是指已经完成两次握手后接收FastCGI应答的超时时间。
fastcgi_buffer_size 64k;
#指定读取FastCGI应答第一部分需要用多大的缓冲区,这个值表示将使用1个64KB的缓冲区读取应答的第一部分(应答头),可以设置为gastcgi_buffers选项指定的缓冲区大小。
fastcgi_buffers 4 64k;
#指定本地需要用多少和多大的缓冲区来缓冲FastCGI的应答请求,如果一个php脚本所产生的页面大小为256KB,那么会分配4个64KB的缓冲区来缓存,如果页面大小大于256KB,那么大于256KB的部分会缓存到fastcgi_temp指定的路径中,但是这并不是好方法,因为内存中的数据处理速度要快于磁盘。一般这个值应该为站点中php脚本所产生的页面大小的中间值,如果站点大部分脚本所产生的页面大小为256KB,那么可以把这个值设置为“8 16K”、“4 64k”等。
fastcgi_busy_buffers_size 128k;
#建议设置为fastcgi_buffer的两倍,繁忙时候的buffer
fastcgi_temp_file_write_size 128k;
#在写入fastcgi_temp_path时将用多大的数据库,默认值是fastcgi_buffers的两倍,设置上述数值设置小时若负载上来时可能报502 Bad Gateway
fastcgi_cache oldboy_ngnix;
#表示开启FastCGI缓存并为其指定一个名称。开启缓存非常有用,可以有效降低CPU的负载,并且防止502的错误放生,但是开启缓存也可能会引起其他问题,要很据具体情况选择
fastcgi_cache_valid 200 302 1h;
#用来指定应答代码的缓存时间,实例中的值表示将2000和302应答缓存一小时,要和fastcgi_cache配合使用
fastcgi_cache_valid 301 1d;
#将301应答缓存一天
fastcgi_cache_valid any 1m;
#将其他应答缓存为1分钟
fastcgi_cache_min_uses 1;
#请求的数量
fastcgi_cache_path /data/ngx_fcgi_cache levels=2:2 keys_zone=ngx_fcgi_cache:512m;
#定义缓存的路径

配置示例:

1
2
3
4
5
6
7
location ~ \.php$ {
trueroot html;
truefastcgi_pass 127.0.0.1:9000;
truefastcgi_index index.php;
truefastcgi_param SCRIPT_FILENAME /www/html/$fastcgi_script_name;
trueinclude fastcgi_params;
}

至于其他的一些模块(例如ngx_http_proxy_module、ngx_http_upstream_module)还听下回分解。



    本文标题   :   nginx配置与优化

    文章作者   :   火柴

    发布时间   :   2016年10月10日 - 11时10分

    本文链接   :   http://www.chen-hao.com.cn/nginx配置与优化.html

    本文字数   :   本文一共有4,251字

    许可协议   :   Attribution-NonCommercial 4.0

    © 转载请保留以上信息,谢谢合作。