技术文章

nginx缓存使用及原理

这几天正好为公共账号写几篇技术文章,就整理一下nginx下的缓存,做web注重性能,webcache使用的好,会事半功倍。

今天重点分析一下web服务器的缓存

一、nginx分为两类缓存,第一类,控制客户端的本地缓存,第二类就是直接缓存地web服务器的文件缓存。

1,expires 指令设置静态文件缓存即使用客户端本地缓存。expires可以控制 http 应答中的“Expires ”和“ Cache-Control ”的头标(起到控制页面缓存的作用),所以在使用浏览器访问的时候,经常可以看到一个状态值304返回.

最常见的静态文件的缓存,配置方式如下:

[well]

location~ .*\.(gif|jpg|png|htm|html|css|js|flv|ico|swf)(.*) {
expires 6h;
}

[/well]

语法: expires [time|epoch|max|off]
默认值: expires off
作用域: http, server, location

设置expires这个参数即可表示需要客户端缓存时间.如果不想让代理或浏览器缓存,加no-cache参数或private参数:
# expires 1d;
add_header Cache-Control no-cache;
add_header Cache-Control private;
这样浏览器F5刷新时,返回的依然是200,而不是304.

分析一下原理,expires使用了特定的时间,在第一次get请求时服务端会在header里返回Last-Modified响应头来确定最后一次修改时间,如果图所示。

 

当客户端第二次访问的时候,request会带有If-Modified-Since响应头来确定缓存时间是否过期,如下图,如果还在缓存时效内,客户端就不会下载缓存内容,服务会返回304,同理时间过了就会重新下载。

总结一下就是客户端使用If-Modified-Since头,和原始服务器中的Last-Modified制作比较,所以实现浏览器缓存并判断是否过期。
简单的说,Last-Modified 与If-Modified-Since 都是用于记录页面最后修改时间的 HTTP 头信息,只是Last-Modified 是由服务器往客户端发送的 HTTP 头,而 If-Modified-Since则是由客户端往服务器发送的头,可以看到,再次请求本地存在的 cache 页面时,客户端会通过 If-Modified-Since头将先前服务器端发过来的 Last-Modified最后修改时间戳发送回去,这是为了让服务器端进行验证,通过这个时间戳判断客户端的页面是否是最新的,如果不是最新的,则返回新的内容,如果是最新的,则返回304告诉客户端其本地cache的页面是最新的,于是客户端就可以直接从本地加载页面了,这样在网络上传输的数据就会大大减少,同时也减轻了服务器的负担。

2,nginx的proxy模块 可以实现类似于Squid的缓存功能,HTTP的缓存与文件系统或者块设备的缓存还有所不同,文件系统或者块设备的缓存可以使用预取方法做优化,提前预取出将要被访问的部分,但是HTTP的缓存却无法预知文件的访问情形。

可以在nginx里面实现动态页面的静态化工作。
具体的配置方法如下:
在http域内添加如下参数

[well]

proxy_temp_path /var/tmp/nginx/proxy;
proxy_cache_path /var/tmp/nginx/cache levels=1:2 keys_zone=cache_one:20m inactive=1d max_size=5g;

server {

 listen  80;
 server_name localhost;

 root /var/www;

 location ~ \.(jpg|png|jpeg|gif|css|js)$ {
  proxy_cache cache_one;
  proxy_cache_valid 200 304 12h;
  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:8181;
  proxy_set_header X-Forwarded_For $proxy_add_x_forwarded_for;
  expires 1d;
 }
}

[/well]

语法解析:

说明

  • proxy_temp_path : 缓存临时目录。后端的响应并不直接返回客户端,而是先写到一个临时文件中,然后被rename一下当做缓存放在 proxy_cache_path 。0.8.9版本以后允许temp和cache两个目录在不同文件系统上(分区),然而为了减少性能损失还是建议把它们设成一个文件系统上。
  • proxy_cache_path ... : 设置缓存目录,目录里的文件名是 cache_key 的MD5值。
    levels=1:2 keys_zone=cache_one:50m表示采用2级目录结构,Web缓存区名称为cache_one,内存缓存空间大小为100MB,这个缓冲zone可以被多次使用。文件系统上看到的缓存文件名类似于 /usr/local/nginx-1.6/proxy_cache/c/29/b7f54b2df7773722d382f4809d65029c 。
    inactive=2d max_size=2g表示2天没有被访问的内容自动清除,硬盘最大缓存空间为2GB,超过这个大学将清除最近最少使用的数据。
  • proxy_cache : 引用前面定义的缓存区 cache_one
  • proxy_cache_key : 定义cache_key
  • proxy_cache_valid : 为不同的响应状态码设置不同的缓存时间,比如200、302等正常结果可以缓存的时间长点,而404、500等缓存时间设置短一些,这个时间到了文件就会过期,而不论是否刚被访问过。

以上两种方式,修改请求url会导致有缓存失效,是因为nginx以请求url做hash为缓存key,只要更新请求url服务器认为是新的请求。

文章总结:

可以看到nginx两种缓存方式,各有所长,根据项目的具体情况联合使用。会对web性能有极大提高.

 

 

 

 

 

 

 

 

 

 

Leave a Reply

Free Web Hosting