nginx从0.7.48版本开始,支持了类似squid的缓存功能。这个缓存是把url及相关组合当作key,用md5编码哈希后保存在硬盘上,所以它可以支持任意url链接,同时也支持404/301/302这样的非200状态码。虽然目前官方的nginx web缓存服务只能为指定url或状态码设置过期时间,不支持类似squid的purge指令,手动清除指定缓存页面,但是,通过一个第三方的nginx 模块,可以清除指定url的缓存。
nginx的web缓存服务主要由proxy_cache相关指令集和fastcgi_cache 相关指令集构成,前者用于反向代理时,对后端内容源服务器进行缓存,后者主要用于对fastcgi的动态程序进行缓存。两者的功能基本上一样。
最新的nginx 0.8.31版本,proxy_cache和fastcgi_cache已经比较完善,加上第三方的ngx_cache_purge模块(用于清除指定 url的缓存),已经可以完全取代squid。我们已经在生产环境使用了 nginx 的 proxy_cache 缓存功能超过两个月,十分稳定,速度不逊于 squid。
在功能上,nginx已经具备squid所拥有的web缓存加速功能、清除指定url缓存的功能。而在性能上,nginx对多核cpu的利用,胜过squid不少。另外,在反向代理、负载均衡、健康检查、后端服务器故障转移、 rewrite重写、易用性上,nginx也比squid强大得多。这使得一台nginx可以同时作为“负载均衡服务器”与“web缓存服务器”来使用。
nginx的基础依赖等这里就不再安装了,我们直接从nginx开始。
wget http://labs.frickle.com/files/ngx_cache_purge-1.0.tar.gz
tar xvzf ngx_cache_purge-1.0.tar.gz
wget http://nginx.org/download/nginx-0.8.31.tar.gz
tar zxvf nginx-0.8.31.tar.gz
cd nginx-0.8.31/
./configure --user=nginx --group=nginx --add-module=../ngx_cache_purge-1.0 --prefix=/home/nginx \
--with-http_stub_status_module
make & make install
以上就安装成功了,下面就是设置/home/nginx/conf/nginx.conf文件了。
下面的命令实在http模块里面,但是又在server模块之上。
proxy_cache_path /tmp/nginx_cache levels=1:2 keys_zone=cache_one:200m inactive=10m max_size=5m
levels指定该缓存空间有两层hash目录,第一层目录是1个字母,第二层为2个字母,保存的文件名就会类似/tmp/nginx_cache/0/da/9cebc9546cefbf52275a01317d96cda0 ;keys_zone为这个空间起个名字,比如上面的cache_one,200m指空间大小为200mb;inactive的10m指缓存默认时长10分钟;max_size的5m是指单个文件超过5m的就不缓存;clean_time指定一分钟清理一次缓存。
接下来就是在server模块里面配置cache了。
proxy_cache_valid 200 304 1h;
proxy_cache_valid 301 302 1h;
proxy_cache cache_one;
proxy_cache_valid any 1m;# 其它文件保存1分钟
# hash key
proxy_cache_key $host$uri$is_args$args;
上面的例子是说http code为200,304,301,302的都缓存一个小时,使用的缓存名称是cache_one,就是在http里面定义的缓存名称。其它类型的缓存时间是1分钟。缓存的文件名是主机名 地址 参数。比如说我们进去看看我们的缓存文件,在目录/tmp/nginx_cache中:
[root@xylz nginx_cache]# ll /tmp/nginx_cache/
总用量 56k
drwx------ 3 nginx nginx 4.0k 1月 28 21:48 0
drwx------ 3 nginx nginx 4.0k 1月 28 21:50 1
drwx------ 3 nginx nginx 4.0k 1月 28 22:04 4
drwx------ 3 nginx nginx 4.0k 1月 28 22:09 5
drwx------ 3 nginx nginx 4.0k 1月 28 21:49 6
drwx------ 5 nginx nginx 4.0k 1月 28 21:49 7
drwx------ 3 nginx nginx 4.0k 1月 28 21:49 8
drwx------ 4 nginx nginx 4.0k 1月 28 22:09 9
drwx------ 3 nginx nginx 4.0k 1月 28 21:49 a
drwx------ 5 nginx nginx 4.0k 1月 28 21:52 b
drwx------ 3 nginx nginx 4.0k 1月 28 21:50 c
drwx------ 5 nginx nginx 4.0k 1月 28 21:48 d
drwx------ 4 nginx nginx 4.0k 1月 28 21:52 e
drwx------ 4 nginx nginx 4.0k 1月 28 21:49 f
[root@xylz nginx_cache]# ll /tmp/nginx_cache/f/
总用量 8.0k
drwx------ 2 nginx nginx 4.0k 1月 28 22:09 2a
drwx------ 2 nginx nginx 4.0k 1月 28 22:02 8b
[root@xylz nginx_cache]# ll /tmp/nginx_cache/f/2a/
总用量 4.0k
-rw------- 1 nginx nginx 2.2k 1月 28 22:09 aaf88d70a381d91b298d3a05f06572af
最后我们使用ngx_purge_module来开放一个地址出来允许手动清除缓存。
location ~ /purge(/.*) {
proxy_cache_purge cache_one $host$1$is_args$args;
}
在上面中$1就表示我们要清除的地址(uri,如果有参数,需要参数)。
好了我们来看一个效果。
www..info get /p/227.html http/1.0 200 9951 0.252 0.252
www..info get /p/227.html http/1.0 200 9951 0.000 -
www..info get /p/227.html http/1.0 200 9951 0.000 -
可以看到除了第一次使用了252毫秒以外,第二次第三次都没有花费后端apache服务器的时间,而且每次发送的字节内容是固定的。实际上这里/p/227.html是wordpress动态生成的内容,默认地址应该是?id=227,只不过我将url重写了,便于搜索引擎爬去而已。
然后我们使用地址/purge/p/227.html来清除缓存。
successful purge
key : www..info/p/227.html
path: /tmp/nginx_cache/9/66/dfea2886862c4eec9ef855215c563
然后再访问就可以看到没有缓存了。
www..info get /p/227.html http/1.0 200 9951 0.262 0.262
当然了,如果想php/jsp等不使用缓存,那么就配一个location,同时不配置proxy_cache即可。location的条件可以如下:
location ~ .*\.(php|jsp|cgi)?$
{
proxy_set_header host $host;
proxy_set_header x-forwarded-for $remote_addr;
proxy_pass http://backend_server;
}