2014年2月10日星期一

nginx 之图片缓存服务器

​      大量的图片需要专业的图片服务器来存放。由于 nginx 可以取代 squid 作为代理缓存使用,今天抽空
试了一把,感觉还是不错的。看过程:
编译:增加一个 cache_purge 模块,用来清缓存。
./configure --prefix=/home/ngx_openresty --with-http_stub_status_module \
--add-module=/root/ngx_cache_purge-master/ --with-pcre=/home/tao.li1/pcre-8.30

nginx 主要配置部分:
    proxy_temp_path /dev/shm/img_temp;
    proxy_cache_path /dev/shm/img_cache levels=1:2 keys_zone=pic_cache:500m inactive=1d max_size=10g;
    server {
        listen       82;
        server_name  sample.com;
        location / {
                proxy_cache pic_cache;
                proxy_cache_valid 200 304 24h;
                proxy_cache_key $host$uri$is_args$args;
                proxy_set_header Host  $host;
                proxy_set_header X-Forwarded-For  $remote_addr;
                proxy_pass http://127.0.0.1:88;
                expires      1d;
                }
        location ~ /purge(/.*) {
            allow       127.0.0.1;
            proxy_cache_purge    pic_cache   $host$1$is_args$args;
        }
    } 
    server {
        listen 88;
        server_name 127.0.0.1;
        root /diska/htdocs/images/;
        location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|ico)$ {
             expires      10s; 
             #expires      -1;
             access_log logs/88pic.log;
        }
    }

测试一下,连续两次访问:
[root@m88 logs]# curl -I 'http://127.0.0.1:82/color.png'
HTTP/1.1 200 OK
Server: ngx_openresty/1.4.3.9
Date: Thu, 02 Jan 2014 03:03:11 GMT
Content-Type: image/png
Content-Length: 892
Connection: keep-alive
Last-Modified: Thu, 12 Apr 2012 08:50:01 GMT
ETag: "4f869739-37c"
Expires: Fri, 03 Jan 2014 03:03:11 GMT
Cache-Control: max-age=86400
Accept-Ranges: bytes

[root@m88 logs]# ls -lh
total 16K
-rw-r--r-- 1 root root 530 Jan  2 11:03 88pic.log
-rw-r--r-- 1 root root 527 Jan  2 11:03 access.log
[root@m88 logs]# curl -I 'http://127.0.0.1:82/color.png'
HTTP/1.1 200 OK
Server: ngx_openresty/1.4.3.9
Date: Thu, 02 Jan 2014 03:03:22 GMT
Content-Type: image/png
Content-Length: 892
Connection: keep-alive
Last-Modified: Thu, 12 Apr 2012 08:50:01 GMT
ETag: "4f869739-37c"
Expires: Fri, 03 Jan 2014 03:03:22 GMT
Cache-Control: max-age=86400
Accept-Ranges: bytes

[root@m88 logs]# ls -lh
total 16K
-rw-r--r-- 1 root root 530 Jan  2 11:03 88pic.log
-rw-r--r-- 1 root root 701 Jan  2 11:03 access.log

通过access log 的大小,我们可以发现, 88pic.log 对 color.png 的访问已经没有新增记录,前端的文件大小有了变化,
说明第二次访问使用的已经是服务器端缓存。要清除这个缓存,只需要:
[root@m88 logs]# curl -I 'http://127.0.0.1:82/purge/color.png'
再来看一下相关细节:

1. curl 获取的 Cache-Control: max-age=86400,和nginx 配置中的前端 expires 对应,这个没有疑问。 

2. 那么实际上图片缓存在服务器上的时间是多少? 还是要依赖 proxy_cache_path 中 inactive 的时间。
我自己做了几个测试,将 后端 88 端口的时间修改为 -1或者no cache (也就是不缓存),proxy_cache_path 
inactive 时间和前端的 expires 都是无效的。即:
proxy_cache_path /dev/shm/img_cache levels=1:2 keys_zone=pic_cache:500m  max_size=10g;
http {
    server {
        listen 82;
        ......
        
        ......
    }
    server {
        listen 88;
        ......
        
        ......
    }
}
上面的配置注定你想要的缓存功能无法实现。

那这个优先级到底是怎样一个关系呢? 经过再后面的几次测试,发现,缓存有效的时间是以 proxy_cache_path 中的
inactive 的值和 后端 88 中 expires 较小的一个值决定的,相等当然最好。也就是如果配置是这样:
proxy_cache_path /dev/shm/img_cache levels=1:2 keys_zone=pic_cache:500m  max_size=10g;
http {
    server {
        listen 82;
        ......
                ......
    }
    server {
        listen 88;
        ......
        
        ......
    }
}
缓存的有效时间是 10s (以后端的为准);我们可以看服务器上的缓存文件(我是通过curl 模拟一次请求),可以看到
这个缓存文件 /dev/shm/img_cache/4/39/40aaedc4a0bd8e5d6e507e7eca39b394 的时间变了:
[root@m88 logs]# curl -I '127.0.0.1:82/color.png' &&
 ls -l /dev/shm/img_cache/4/39/40aaedc4a0bd8e5d6e507e7eca39b394 &&
 sleep 90 && curl -I '127.0.0.1:82/color.png' &&
 ls -l /dev/shm/img_cache/4/39/40aaedc4a0bd8e5d6e507e7eca39b394

HTTP/1.1 200 OK
Server: ngx_openresty/1.4.3.9
Date: Thu, 02 Jan 2014 06:31:50 GMT
Content-Type: image/png
Content-Length: 892
Connection: keep-alive
Last-Modified: Thu, 12 Apr 2012 08:50:01 GMT
ETag: "4f869739-37c"
Expires: Thu, 02 Jan 2014 06:31:49 GMT
Cache-Control: no-cache
Accept-Ranges: bytes

-rw------- 1 nobody nobody 1267 Jan  2  /dev/shm/img_cache/4/39/40aaedc4a0bd8e5d6e507e7eca39b394
HTTP/1.1 200 OK
Server: ngx_openresty/1.4.3.9
Date: Thu, 02 Jan 2014 06:33:20 GMT
Content-Type: image/png
Content-Length: 892
Connection: keep-alive
Last-Modified: Thu, 12 Apr 2012 08:50:01 GMT
ETag: "4f869739-37c"
Expires: Thu, 02 Jan 2014 06:33:19 GMT
Cache-Control: no-cache
Accept-Ranges: bytes

-rw------- 1 nobody nobody 1267 Jan  2  /dev/shm/img_cache/4/39/40aaedc4a0bd8e5d6e507e7eca39b394

对比两个 access log 可以发现
[root@m88 logs]# ls -lh
total 16K
-rw-r--r-- 1 root root 875 Jan  2 14:33 88pic.log
-rw-r--r-- 1 root root 870 Jan  2 14:33 access.log
也都是两次请求。所以这个 expires 是 10s, 认为过期后会从服务器上重新去取。那么如果配置是这样:
proxy_cache_path /dev/shm/img_cache levels=1:2 keys_zone=pic_cache:500m  max_size=10g;
http {
    server {
        listen 82;
        ......
        
        ......
    }
    server {
        listen 88;
        ......
        
        ......
    }
}

我们可以理解为缓存文件 /dev/shm/img_cache 在10s 内无请求,自动清除,需要重新下载一份作为缓存,所以需要访问后端。有效时间仍然是 10s。

3. 主要是关于 proxy_cache_path 中的参数:
   1) levels 指定目录的层次,这个比较好理解。最多好像是三层目录。
   2) keys_zone 设置缓存名字和共享内存大小;名字不多说,主要说大小,这里是针对单个nginx 进程最大可以使用多大内存来保留;
   3) inactive 删除过期文件的时间,默认好像是10 分钟,如果删了,必须重新缓存;
   4) max_size 最多使用的大小,这里是指定的使用目录如 /dev/shm/img_cache 大小。

没有评论:

发表评论