404错误驱动Web缓存
Nginx服务器的这一种实现Web缓存的原理其实很简单,主要还是依靠自身的Proxy Store功能对404错误进行重定向来实现。当Nginx服务器在处理客户端请求时,发现请求的资源数据不存在,会产生404错误,然后服务器通过捕获该错误,进一步转向后端服务器请求数据,最后将后端服务器的响应数据传回客户端,同时在本地进行缓存。从实现-原理上来看,Nginx服务器向后端服务器发起数据请求并完成Web缓存,主要是由产生的404错误驱动的。
请大家看一个简单的实现404错误驱动Web缓存的配置方案片段:
...
location / {
...
root /myweb/server/;
error_page 404 =200 /errpage
}
location /errpage/ {
...
internal;
alias /home/html;
proxy_pass http://backend;
proxy_set_header Accept-Encoding "''; #后端不返回要锁(gzip/deflate)数据
proxy_store on; #指定Nginx将代理返回的文件保存
proxy_store_access user:rw group:rw all:r; #配置缓存数据的访问权限
proxy_temp_path /myweb/server/tmp; #配置临时目录,该目录要和/myweb/server/在同一个硬盘分区内
}
配置将404错误响应进行重定向,然后使用location块捕获重定向请求,向后端服务器发起请求获取响应数据,然后将数据转发给客户端的同时缓存到本地。
资源不存在驱动Web缓存
该方法同“404错误驱动Web缓存”的方法的原理上大同小异,不同之处是,该方法是通过location块的location if条件判断直接驱动Nginx服务器与后端服务器的通信和Web缓存,而后者是对资源不存在引发的404错误进行捕获,进而驱动Nginx服务器与后端服务器的通信和Web缓存。
再看一个简单的通过判断资源不存在的驱动Web缓存的配置方案片段:
···nginx
...#其他配置
location / {
...#其他配置
root /home/html/;
internal;; #配置该为目录不能通过外部链接直接访问
alias /myweb/server/;
proxy_set_header Accept-Encoding "''; #配置后端不反悔要锁(gzip或deflate)数据
proxy_store on; #指定nginx将代理返回的文件保存
proxy_store_access user:w group:rw all:r; #配置缓存数据的访问权限
proxy_temp_path /myweb/server/tmp; #配置临时目录,该目录要和/myweb/server/在同一个硬盘分区内
if(!-f $request_filename) #判断请求资源是否存在
{
proxy_pass http://backend/; #配置后端upstream地址或者源地址
}
}
在配置实例中使用location if条件判断支持的“!-f”判断请求的资源在Nginx服务器上是否存在,如果不存在就通过后端服务器获取数据,然后回传给客户端,同时使用Proxy Store进行缓存。
以上两种缓存机制在原理上是相近的,在实际的应用中,我们通常可以将Proxy Store的缓存目录配置到/dev/shm中提高缓存数据的处理速度。如果不是在内存中保存缓存数据,这两种缓存机制不支持缓存数据的清理机制,缓存文件会一直保存在本地占用硬盘空间。
这两种缓存机制还有需要注意的地方是它们只能缓存200状态吗下的响应数据,这就是为什么我们在介绍“404错误驱动Web缓存”机制时配置实例中将404错误重新改写为200状态的原因。
两种缓存机制也不支持动态链接的请求。比如getsource?id=1和getsource?id=2这两个请求,这两种缓存机制会忽略id=1参数,从而造成返回的资源不正确等问题。这是两种缓存机制的缺点,但在实际应用中也有一定的使用价值。
## 基于memcached的缓存机制
memcached是一套高性能的基于分布式的缓存系统,用于动态Web应用以减轻后台服务器的负载。memcached可以处理并发的网络连接。它在内存中开辟一块空间,然后建立一个hash表,将缓存数据通过键/值存储在Hash表中进行管理。memcached由服务端和客户端两个核心组件组成,服务端先通过计算“键”的hash值来确定键/值对所在的服务器所处的位置。当确定键/值对的位置后,客户端就会发送一个查询请求给对应的服务端,让它来查找并返回确切的数据。
在Nginx服务器的标准HTTP模块中有一个ngx_http_memcached_module模块,专门用于处理和memcached相关的配置和功能实现,虽然在目前的版本中还没有支持完整的功能,但是其性能很好,对于一般的应用场景是比较好的选择方案。
## Proxy Cache缓存机制
Proxy Cache机制是Nginx服务器自己实现的类似于Squid的缓存机制,它使用md5算法将请求链接hash后生成文件系统目录保存响应数据。
Nginx服务器在启动后,会生成专门的进程对磁盘上的缓存文件进行扫描,在内存中建立缓存索引,提高访问效率,而且还会生成专门的管理进程对磁盘上的缓存文件进行过期判断,更新等方面的管理。Proxy Cache缓存机制支持对任意链接响应数据的缓存,不仅限于200状态时的数据。
Proxy Cache缓存机制的一个缺陷是,他没有实现自动清理磁盘上缓存数据的功能,因此在长时间使用过程中对服务器存储造成一定的压力。
在下面的配置中,实现了Nginx服务器Proxy Cache缓存机制的一般配置:
```nginx
...#其他配置
http {
...#其他配置
proxy_cache_path /myweb/server/proxycache levels=1:2 max_size=2m inactive=5m
loader_sleep=1m; keys_zone=MYPROXYCACHE:10m #配置了缓存数据存放路径和Proxy Cache使用
proxy_temp_path /myweb/server/tmp; #配置响应数据的临时存放目录
server {
...... #其他配置
proxy_pass http://www.myweb.name/; #配置使用MYPROXYCACHE这个keys_zone
proxy_cache MYPROXYCACHE; # 配置200状态和302状态的响应缓存1小时
proxy_cache_valid 200 302 1h; #配置200和302状态的响应缓存1小时
proxy_cache_valid 301 1d; #配置301状态的响应缓存1天
proxy_cache_valid any 1m; #配置其他状态的响应数据缓存1分钟
}
}
在该实例中,我们首先在http块中配置了缓存数据存放路径和Proxy Cache使用的内存Cache空间。缓存数据存放在磁盘上/myweb/server/proxycache目录下,它包含两级hash目录,缓存数据的总量不能超过20MB、如果缓存在5分钟内没有被访问,则强制更新。内存Cache空间的名字为MYPROXYCACHE,大小不能超过10MB,每隔1分钟遍历一次磁盘缓存源数据,更新内存Cache中的缓存索引。
之后,我们在server块中,配置使用上面设置好的MYPROXYCACHE内存空间进行Proxy Cache工作,对不同响应状态的数据缓存时间进行了配置。
Proxy Cache机制是Nginx服务器自身实现的一个功能比较完整、性能也不错的缓存机制,在实际应用过程后者能够使用比较广泛。
Nginx与Squid组合
Squid Cache(简称Squid)是目前在大访问量的网站建设中应用非常广泛的Web缓存服务器。它可以作为网页服务器的前置缓存服务器来缓存相关的请求数据,也可以缓存公网资源为局域网内用户提供共享资源。但是,Squid服务本身不支持在单台服务器同一端口(例如要反向道理Web必须制定80端口)下运行多个进程,这样的话就需要给每一个Squid服务分配一台服务器设备,这样非常浪费资源。
Nginx具有反向代理服务功能,支持服务器组的配置和对组间服务器的轮询,我们可以运用Nginx的这一功能,实现在同一台服务器中运行多个Squid服务的目的。