nginx安装配置参考:http://freeloda.blog.51cto.com/2033581/1288553
1.指令说明
proxy_cache_path
语法:proxy_cache_path path [levels=number] keys_zone=zone_name:zone_size [inactive=time] [max_size=size];
默认值:None
使用字段:http
指令指定缓存的路径和一些其他参数,缓存的数据存储在文件中,并且使用代理url的哈希值作为关键字与文件名。levels参数指定缓存的子目录数,例如:
1
|
proxy_cache_path
/data/nginx/cache
levels=1:2 keys_zone=one:10m;
|
文件名类似于:
1
|
/data/nginx/cache/c/29/b7f54b2df7773722d382f4809d65029c
|
levels指定目录结构,可以使用任意的1位或2位数字作为目录结构,如 X, X:X,或X:X:X 例如: “2”, “2:2”, “1:1:2“,但是最多只能是三级目录。
所有活动的key和元数据存储在共享的内存池中,这个区域用keys_zone参数指定。one指的是共享池的名称,10m指的是共享池的大小。
注意每一个定义的内存池必须是不重复的路径,例如:
1
2
3
|
proxy_cache_path
/data/nginx/cache/one
levels=1 keys_zone=one:10m;
proxy_cache_path
/data/nginx/cache/two
levels=2:2 keys_zone=two:100m;
proxy_cache_path
/data/nginx/cache/three
levels=1:1:2 keys_zone=three:1000m;
|
如果在inactive参数指定的时间内缓存的数据没有被请求则被删除,默认inactive为10分钟。一个名为cache manager的进程控制磁盘的缓存大小,它被用来删除不活动的缓存和控制缓存大小,这些都在max_size参数中定义,当目前缓存的值超出max_size指定的值之后,超过其大小后最少使用数据(LRU替换算法)将被删除。内存池的大小按照缓存页面数的比例进行设置,一个页面(文件)的元数据大小按照操作系统来定,如FreeBSD/i386下为64字节,FreeBSD/amd64下为128字节。
proxy_cache
语法:proxy_cache zone_name;
默认值:None
使用字段:http, server, location
设置一个缓存区域的名称,一个相同的区域可以在不同的地方使用。
在0.7.48后,缓存遵循后端的”Expires”, “Cache-Control: no-cache”, “Cache-Control: max-age=XXX”头部字段,0.7.66版本以后,”Cache-Control:“private”和”no-store”头同样被遵循。nginx在缓存过程中不会处理”Vary”头,为了确保一些私有数据不被所有的用户看到,后端必须设置 “no-cache”或者”max-age=0”头,或者proxy_cache_key包含用户指定的数据如$cookie_xxx,使用cookie的值作为proxy_cache_key的一部分可以防止缓存私有数据,所以可以在不同的location中分别指定proxy_cache_key的值以便分开私有数据和公有数据。
缓存指令依赖代理缓冲区(buffers),如果proxy_buffers设置为off,缓存不会生效。
proxy_cache_valid
语法:proxy_cache_valid reply_code [reply_code …] time;
默认值:None
使用字段:http, server, location
为不同的应答设置不同的缓存时间,例如:
1
2
|
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
|
为应答代码为200和302的设置缓存时间为10分钟,404代码缓存1分钟。
如果只定义时间:
1
|
proxy_cache_valid 5m;
|
那么只对代码为200, 301和302的应答进行缓存。
同样可以使用any参数任何应答。
1
2
3
|
proxy_cache_valid 200 302 10m;
proxy_cache_valid 301 1h;
proxy_cache_valid any 1m;
|
2.定义一个简单nginx缓存服务器
[root@nginx ~]
# vim /etc/nginx/nginx.conf
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"'
#access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
upstream webservers{
ip_hash;
server 172.16.16.41:80 weight=1 max_fails=2 fail_timeout=30s;
server 172.16.16.42:80 weight=1 max_fails=2 fail_timeout=30s;
}
proxy_cache_path
/data/nginx/cache/webserver
levels=1:2 keys_zone=webserver:20m max_size=1g;
server {
listen 80;
server_name 175.102.13.55;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
proxy_pass http://webservers;
proxy_set_header Host $host;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache webserver;
proxy_cache_valid 200 10m;
}
}
3.新建缓存目录
1
|
[root@nginx ~]
# mkdir -pv /data/nginx/cache/webserver
|
4.重新加载一下配置文件
1
2
3
4
|
[root@nginx webserver]
# service nginx reload
nginx: the configuration
file
/etc/nginx/nginx
.conf syntax is ok
nginx: configuration
file
/etc/nginx/nginx
.conf
test
is successful
重新载入 nginx: [确定]
|
5.下面我们来测试一下(谷歌浏览器)
注,大家用谷歌浏览器测试的时候,可以按F12调用开发工具,选择Network选项,我们可以看到,Response Headers,在这里我们可以看到,我们请求的是否是缓存,但现在还看不到被命中。
6.进行相关配置修改
$server_addr
服务器地址,在完成一次系统调用后可以确定这个值,如果要绕开系统调用,则必须在listen中指定地址并且使用bind参数。
$upstream_cache_status
0.8.3版本中其值可能为:
MISS 未命中
EXPIRED - expired。请求被传送到后端。
UPDATING - expired。由于proxy/fastcgi_cache_use_stale正在更新,将使用旧的应答。
STALE - expired。由于proxy/fastcgi_cache_use_stale,后端将得到过期的应答。
HIT 命中
[root@nginx ~]
# vim /etc/nginx/nginx.conf
proxy_cache_path
/data/nginx/cache/webserver
levels=1:2 keys_zone=webserver:20m max_size=1g;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
#增加两头部
add_header X-Via $server_addr;
add_header X-Cache $upstream_cache_status;
location / {
root html;
index index.html index.htm;
proxy_pass http://webservers;
proxy_set_header Host $host;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache webserver;
proxy_cache_valid 200 10m;
}
7.重新加载一下配置文件
1
2
3
4
|
[root@nginx ~]
# service nginx reload
nginx: the configuration
file
/etc/nginx/nginx
.conf syntax is ok
nginx: configuration
file
/etc/nginx/nginx
.conf
test
is successful
重新载入 nginx: [确定]
|
8.测试一下
注,从图中我们可以看到,我们访问的服务器是175.102.13.55,缓存命中。大家可以看到是不是很直观啊。下面我们看一下缓存目录。
[root@localhost ~]# cd /data/nginx/cache/webserver/
[root@localhost webserver]# ll
总用量 12
drwx------. 3 nginx nginx 4096 3月 4 10:56 1
drwx------. 3 nginx nginx 4096 3月 4 12:53 9
drwx------. 3 nginx nginx 4096 3月 4 11:09 f
[root@localhost webserver]# cd f/63/
[root@localhost 63]# ls
681ad4c77694b65d61c9985553a2763f
[root@localhost 63]#
注,缓存目录里确实有缓存文件。好了,nginx缓存配置就到这边了,更多配置请根据需要看配置文档。
二:nginx cache命中率统计
参考:http://www.361way.com/nginx-cache/2665.html
http://www.libertyvps.com/thread-275-1-1.html
即然nginx为我们提供了$upstream_cache_status函数,自然可以将命中状态写入到日志中。具体可以如下定义日志格式:
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'
'"$upstream_cache_status"';
access_log /var/log/nginx/access.log main;
命中率统计方法:用HIT的数量除以日志总量得出缓存命中率:
awk '{if($NF=="\"HIT\"") hit++} END {printf "%.2f%",hit/NR}' /var/log/nginx/access.log
也可以通过crontab脚本将每天的命中率统计到一个日志中,以备查看。
# crontab -l
1 0 * * * /opt/shell/nginx_cache_hit >> /var/log/nginx/hit
创建一个脚本nginx_cache_hit,查看一下脚本内容如下:
# cat /opt/shell/nginx_cache_hit
#!/bin/bash
LOG_FILE='/var/log/nginx/access.log.1'
LAST_DAY=$(date +%F -d "-1 day")
awk '{if($NF=="\"HIT\"") hit++} END {printf "'$LAST_DAY': %d %d %.2f%\n", hit,NR,hit/NR}' $LOG_FILE