使用Nginx的proxyCache缓存功能


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 
  . 
  imxylz 
  . 
  info GET  
  / 
  p 
  / 
  227 
  . 
  html HTTP 
  / 
  1.0 
    
  200 
    
  9951 
    
  0.252 
    
  0.252 
  
 www 
  . 
  imxylz 
  . 
  info GET  
  / 
  p 
  / 
  227 
  . 
  html HTTP 
  / 
  1.0 
    
  200 
    
  9951 
    
  0.000 
    
  - 
  
 www 
  . 
  imxylz 
  . 
  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 
  . 
  imxylz 
  . 
  info 
  / 
  p 
  / 
  227 
  . 
  html
             Path 
  : 
    
  / 
  tmp 
  / 
  nginx_cache 
  / 
  9 
  / 
  66 
  / 
  dfea2886862c4eec9ef855215c563


然后再访问就可以看到没有缓存了。



www 
  . 
  imxylz 
  . 
  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;
             }