Nginx系列——Nginx配置与优化
Nginx配置与优化
include使用
当我们配置多个虚拟主机在nginx配置文件中的时候,我们会越来越发现,nginx.conf文件越来越大,维护起来也越来越麻烦,这个时候我们就需要使用include,把每个虚拟主机配置到自己的conf中,然后在nginx.conf中include就可以了。1
2
3
4
5#目录
nginx.conf
site/
www_abc_com.conf
www_edf_com.conf
1 | #nginx.conf配置 |
当然一些特殊功能模块的配置也可以独立出一个单一的配置文件,这样nginx.conf的结构会很清晰。
目录配置(root&alias)
Nginx的目录配置一般有2种方式,一个是root,另一个是alias;它们最主要的区别是:alias指定的目录是准确的,root是指定目录的上级目录。1
2
3
4location /static/ {
root /var/html/;
}
#如果访问路径是“www.xxx.com/static/a.js”,实际指向“/var/html/static/a.js”;
1 | lcoation /static/ { |
nginx还有一个指令用来打开目录的浏览功能,那就是“autoindex”。1
2
3
4
5
6
7
8
9
10
11location /image/ {
#on:表示打开目录浏览功能,默认为off
autoindex on;
#on:显示出文件的确切大小,单位是bytes;默认为on
#off:显示出文件的大概大小,单位是kB或者MB或者GB
autoindex_exact_size off;
#on:显示的文件时间为文件的服务器时间
#off:显示的文件时间为GMT时间,默认为off
autoindex_localtime on;
alias /var/html/image/;
}
过期设置(expires)
1 | location ~* ^.+\.(ico|gif|jpg|jpeg|png|html|htm)$ { |
expires
语法:expires [time|epoch|max|pff]
默认值: expires off
作用域: http, server, location
expires指令通过控制HTTP应答中的“Expires”和“Cache-Control”Header头部信息,达到控制页面缓存的作用
time:可以是正数或者负数,控制“Expires”的值为当前时间+time的值,也可以控制“Cache-Control”的值,负数表示“no-cache”,正数或0 表示max-age=time。
如果加日期后缀的话,1
2
3
4
5
6
7
8ms: milliseconds 毫秒
s: seconds 秒
m: minutes 分钟
h: hours 小时
d: days 天
w: weeks 周
M: months (30 days) 月
y: years (365 days), 年
不加默认表示秒数,后缀可以多个一起使用。例如:“expires 1h30m”表示1小时30分钟后过期,“expires 1y1M”表示1年1个月后过期;
time也可以使用绝对时间,只要使用“@”符号,如“expires @10:20” 表示过期时间为10:20这个时间点。
epoch:表示自1970年一月一日00:00:01 GMT的绝对时间,很少用。
max:指定Expires的值为2037年12月31日23:59:59,Cache-Control的值为10 years。
获取客户端真实IP
为了后端服务器能获取到客户端真实的IP,需要在配置安装Nginx的时候加上—with-http_realip_module模块,然后在nginx.conf加入如下配置。1
2
3proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
负载均衡
1 | http{ |
upstream的配置详情请查看Nginx模块-upstream。
访问控制
限制IP
Nginx可以限制和允许IP访问,但是你必须要在安装的时候配置–without-http_access_module,从而加入ngx_http_geo_module模块1
2
3
4
5
6
7
8
9
10location / {
#deny 限制
deny 192.168.1.1;
#allow 允许192.168.1.0-192.168.1.254范围的IP
allow 192.168.1.0/24;
#allow 允许10.1.0.0-10.1.255.254范围的IP
allow 10.1.0.0/16;
deny all;
#匹配从上到下执行,匹配到就跳出,deny all就是拒绝所有
}
限制目录
1 | location /admin { |
限制速度
1 | location /download { |
1 | location /download { |
限制请求数
Nginx有2个模块可以实现限制请求数,一个是HttpLimitReqModul,它限制的是一个ip在一段时间内的访问次数,另外一个是HttpLimitConnModul,它限制的是一个ip某个时刻的并发数。
HttpLimitReqModul
1 | http{ |
HttpLimitConnModul
1 | http{ |
启动gzip压缩
Nginx支持gzip压缩,对输出的数据流进行实时压缩。1
2
3
4
5
6
7
8
9gzip on;
gzip_disable "msie6";
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_proxied any;
gzip_comp_level 4;
gzip_types text/plain application/x-javascript text/css application/xml
gzip_vary on;
gzip_http_version 1.0;
gzip on|off
默认值: gzip off
作用域: http, server, location, if (x) location
开启或者关闭gzip模块。
gzip_disable “MSIE [1-6].”
作用域: http, server, location
禁用IE6以下版本的gzip压缩,因为坑爹的IE6。
gzip_min_length 1k
默认值:gzip_min_length 0
作用域: http, server, location
作用:设置允许压缩的页面最小字节数,页面字节数从header头中的Content-Length中进行获取。
默认值是0,不管页面多大都压缩,建议设置成大于1k的字节数,小于1k可能会越压越大。
gzip_buffers 4 16
默认值: gzip_buffers 4 4k/8k
作用域: http, server, location
设置系统获取几个单位的缓存用于存储gzip的压缩结果数据流。例如 4 4k代表以4k为单位,按照原始数据大小以4k为单位的4倍申请内存。 4 8k代表以8k为单位,按照原始数据大小以8k为单位的4倍申请内存。
如果没有设置,默认值是申请跟原始数据相同大小的内存空间去存储gzip压缩结果。
gzip_proxied
语法: gzip_proxied [off|expired|no-cache|no-store|private|no_last_modified|no_etag|auth|any] …
默认值: gzip_proxied off
作用域: http, server, location
Nginx作为反向代理的时候启用,开启或者关闭后端服务器返回的结果,匹配的前提是后端服务器必须要返回包含”Via”的 header头。
off - 关闭所有的代理结果数据的压缩
expired - 启用压缩,如果header头中包含 “Expires” 头信息
no-cache - 启用压缩,如果header头中包含 “Cache-Control:no-cache” 头信息
no-store - 启用压缩,如果header头中包含 “Cache-Control:no-store” 头信息
private - 启用压缩,如果header头中包含 “Cache-Control:private” 头信息
no_last_modified - 启用压缩,如果header头中不包含 “Last-Modified” 头信息
no_etag - 启用压缩 ,如果header头中不包含 “ETag” 头信息
auth - 启用压缩 , 如果header头中包含 “Authorization” 头信息
any - 无条件启用压缩
gzip_comp_level 4
语法: gzip_comp_level 1..9
默认值: gzip_comp_level 1
作用域: http, server, location
gzip压缩比,1 压缩比最小处理速度最快,9 压缩比最大但处理最慢(传输快但比较消耗cpu),所有一般设置了居中的4就可以了。
gzip_types
默认值: gzip_types text/html
作用域: http, server, location
匹配MIME类型进行压缩,(无论是否指定)”text/html”类型总是会被压缩的。
gzip_vary on|off
默认值: gzip_vary off
作用域: http, server, location
和http头有关系,加个vary头,给代理服务器用的,有的浏览器支持压缩,有的不支持,所以避免浪费不支持的也压缩,所以根据客户端的HTTP头来判断,是否需要压缩.
gzip_http_version
默认值: gzip_http_version 1.1
作用域: http, server, location
gzip_http_version的设置,它的默认值是1.1,就是说对HTTP/1.1协议的请求才会进行gzip压缩
Nginx在使用gzip压缩的时候,一般会配合开启客户端的Cache,不然每次请求Nginx都压缩一遍返回,增加服务器的性能开销;其实nginx还有支持预编译的压缩GzipPrecompression模块,就是事先手动的压缩好文件,请求过来的时候不需要动态压缩,直接读取压缩好的文件。
首先需要在编译配置的时候加上—with-http_gzip_static_module,然后在nginx.conf配置文件中加入gzip_static on;,然后就是需要对需要压缩的文件如.css,.js.html文件用gzip压缩为同名的gz文件,
具体大家可以参考巧用Nginx的GzipStatic模块来减少服务器资源占用.
Proxy Cache
使用Nginx的proxy cache模块实现对静态文件的缓存1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23http{
...
#设置proxy cache的保存硬盘路径为/data/nginx/cache/one;
#keys_zone=one:10m 表示这个zone名称为one,分配的内存大小为10MB
#levels=1:2 表示缓存目录的第一级目录是1个字符,第二级目录是2个字符,即
#/data/nginx/cache/one/a/2b;
#inactive=1d 表示这个zone中的缓存文件如果在1天内都没有被访问,那么文件会
#被cache manager进程删除掉,默认设置为10m;
#max_size=5g表示这个zone的硬盘容量为5GB
proxy_cache_path /data/nginx/cache/one levels=1:2 keys_zone=one:10m inactive=1d max_size=5g;
location ~ .(jpg|png|gif|css|js)$ {
proxy_pass http://127.0.0.1:8001;
#设置资源缓存的zone
proxy_cache one;
#设置缓存的key
proxy_cache_key $host$uri$is_args$args;
#设置状态码为200和304的响应可以进行缓存,并且缓存时间为10分钟
proxy_cache_valid 200 304 10m;
expires 30d;
}
}
其他相关的配置详情可以查看Nginx-wiki-HttpProxyModul。
日志切割
通过信号来实现Nginx的日志切割:1
2
3
4
5
6TERM, INT #快速关闭
QUIT #从容关闭
HUP #平滑重启,重新加载配置文件
USR1 #重新打开日志文件,可以用于日志切割
USR2 #平滑升级可执行程序。
WINCH #从容关闭工作进程
切割日志脚本nginx_log_cut.sh如下:1
2
3
4
5
6
7
8
9#!/bin/bash
#设置日志文件存放路径
log_path="/usr/local/nginx/logs/"
#设置pid文件
pid_path="/usr/local/nginx/nginx.pid"
#重命名日志文件
mv ${log_path}access.log ${log_path}access_$(date -d "yesterday" +"%Y%m%d").log
#向nginx主进程发信号重新打开日志
kill -USR1 `cat ${pid_path}`
在定时作业crontab里加入下面一句话1
0 0 * * * bash /usr/local/nginx/nginx_log_cut.sh
server_name匹配顺序
1、准确的server_name匹配1
2
3
4
5server {
listen 80;
server_name domain.com www.domain.com; //多个使用空格隔开
...
}
2、以*通配符开始的字符串1
2
3
4
5server {
listen 80;
server_name *.domain.com;
...
}
3、以*通配符结束的字符串1
2
3
4
5server {
listen 80;
server_name www.*;
...
}
4、匹配到的正则表达式1
2
3
4
5
6//使用正则表达式,前面需要加上“~”
server {
listen 80;
server_name ~^(?.+)\.domain\.com$;
...
}
nginx将按照1,2,3,4的顺序对server_name进行匹配,只有有一项匹配以后就会停止搜索.
server_name指令一项很实用的功能便是可以在使用正则表达式的捕获功能,这样可以尽量精简配置文件。
1、在一个server块中配置多个站点:1
2
3
4
5
6
7
8
9
10
11server{
listen 80;
server_name ~^(www\.)?(.+)$;
index index.php index.html;
root /data/wwwsite/$2;
}
匹配:
/data/wwwsite/domain.com
/data/wwwsite/nginx.org
/data/wwwsite/baidu.com
/data/wwwsite/google.com
2、在一个server块中为一个站点配置多个二级域名1
2
3
4
5
6
7
8
9
10
11
12server{
listen 80;
server_name ~^(.+)?\.domain\.com$;
index index.html;
if ($host = domain.com){
rewrite ^ http://www.domain.com permanent;
}
root /data/wwwsite/domain.com/$1/;
}
匹配:
/data/wwwsite/domain.com/www/
/data/wwwsite/domain.com/nginx/
参考:
【1】 http://onlyzq.blog.51cto.com/1228/535279
【2】 http://tengine.taobao.org/book/