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_oneproxy_cache_key
: 定义cache_keyproxy_cache_valid
: 为不同的响应状态码设置不同的缓存时间,比如200、302等正常结果可以缓存的时间长点,而404、500等缓存时间设置短一些,这个时间到了文件就会过期,而不论是否刚被访问过。
以上两种方式,修改请求url会导致有缓存失效,是因为nginx以请求url做hash为缓存key,只要更新请求url服务器认为是新的请求。
文章总结:
可以看到nginx两种缓存方式,各有所长,根据项目的具体情况联合使用。会对web性能有极大提高.