这一篇记录一下Nginx作为Web服务器缓存,减少对应用服务器请求次数 ,各位看到此博客的小伙伴,如有不对的地方请及时通过私信我或者评论此博客的方式指出,以免误人子弟。多谢!

Nginx作为Web缓存服务器,它介于客户端和应用服务器之间,当用户通过浏览器访问一个URL时,web缓存服务器会去应用服务器获取要展示给用户的内容,将内容缓存到自己的服务器上,当下一次请求到来时,如果访问的是同一个URL,web缓存服务器就会直接将之前缓存的内容返回给客户端,而不是向应用服务器再次发送请求。web缓存降低了应用服务器、数据库的负载,减少了网络延迟,提高了用户访问的响应速度,增强了用户的体验。

目录

原理

相关指令

proxy_cache_path

proxy_cache

proxy_cache_key

proxy_cache_valid

proxy_cache_min_uses

proxy_cache_methods

测试案例

环境准备

tomcat

Nginx配置

测试

清除缓存

nginx配置并测试

设置不缓存的数据

相关指令

proxy_no_cache

proxy_cache_bypass

测试


原理

Nginx是从0.7.48版开始提供缓存功能。Nginx是基于Proxy Store来实现的,其原理是把URL及相关组合当做Key,在使用MD5算法对Key进行哈希,得到硬盘上对应的哈希目录路径,从而将缓存内容保存在该目录中。

相关指令

Nginx的web缓存服务主要是使用ngx_http_proxy_module模块相关指令完成。

proxy_cache_path

该指定用于设置缓存文件的存放路径。

语法proxy_cache_path path [levels=number] keys_zone=zone_name:zone_size [inactive=time][max_size=size];
默认值
位置http

path:缓存路径地址,如:/usr/local/proxy_cache。

levels: 指定该缓存空间对应的目录,最多可以设置3层,每层取值为1|2如 :

levels=1:2   缓存空间有两层目录,第一次是1个字母,第二次是2个字母,从MD5字符串倒序取值。
举例说明:
itheima[key]通过MD5加密以后的值为 43c8233266edce38c2c9af0694e2107d
levels=1:2   最终的存储路径为/usr/local/proxy_cache/d/07
levels=2:1:2 最终的存储路径为/usr/local/proxy_cache/7d/0/21
levels=2:2:2 最终的存储路径为??/usr/local/proxy_cache/7d/10/e2

keys_zone:用来为这个缓存区设置名称和指定大小。

inactive:指定缓存的数据多次时间未被访问就将被删除,如:

inactive=1d   缓存数据在1天内没有被访问就会被删除。

max_size:设置最大缓存空间,如果缓存空间存满,默认会覆盖缓存时间最长的资源。

配置实例:

http{
	proxy_cache_path /usr/local/proxy_cache keys_zone=yjh:200m  levels=1:2:1 inactive=1d max_size=20g;
}

proxy_cache

该指令用来开启或关闭代理缓存,如果是开启则自定使用哪个缓存区来进行缓存。

语法proxy_cache zone_name|off;
默认值proxy_cache off;
位置http、server、location

zone_name:指定使用缓存区的名称。

proxy_cache_key

该指令用来设置web缓存的key值,Nginx会根据key值MD5哈希存缓存。

语法proxy_cache_key key;
默认值proxy_cache_key $scheme$proxy_host$request_uri;
位置http、server、location

proxy_cache_valid

该指令用来对不同返回状态码的URL设置不同的缓存时间。

语法proxy_cache_valid [code ...] time;
默认值
位置http、server、location

proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
为200和302的响应URL设置10分钟缓存,为404的响应URL设置1分钟缓存
proxy_cache_valid any 1m;
对所有响应状态码的URL都设置1分钟缓存

proxy_cache_min_uses

该指令用来设置资源被访问多少次后被缓存。

语法proxy_cache_min_uses number;
默认值proxy_cache_min_uses 1;
位置http、server、location

proxy_cache_methods

该指令用户设置缓存哪些HTTP方法。

语法proxy_cache_methods GET|HEAD|POST;
默认值proxy_cache_methods GET HEAD;
位置http、server、location

默认缓存HTTP的GET和HEAD方法,不缓存POST方法。

测试案例

 如上,我在阿里服务器上有一个tomcat,端口8080,在webapps目录下新建一个js目录并放入一个js文件,还有一个Nginx,监听8090端口,我们希望在客户端发送请求获取获取应用服务器资源的时候,先经过Nginx,Nginx从应用服务器获取到资源后返回客户端,并缓存一份到配置的/usr/local/proxy_cache目录下,下次客户端再次访问同样的资源,就不必再去应用服务器获取,Nginx直接返回缓存的就可以啦。

环境准备

tomcat

启动tomcat,浏览器访问 http://190.118.52.56:8080/js/jquery-1.10.1.js 可以正常返回js的内容。

Nginx配置

在http块中添加一个server块监听8090端口,并添加upstream块和proxy_cache_path

proxy_cache_path /usr/local/proxy_cache levels=2:1 keys_zone=yjh:200m inactive=1d max_size=20g;

    upstream backend{
        server localhost:8080;
    }
    server {
        listen 8090;
        server_name localhost;
        location / {
                proxy_cache yjh; # 指定使用缓存区的名称,注意要与 proxy_cacha_path中keys_zone指定的一致
                proxy_cache_valid 200 5d; # 为200响应码的请求设置缓存时间为5天
                proxy_pass http://backend/js/;
        }
    }

测试

确保tomcat和nginx都正常启动后,浏览器访问 http://190.118.52.56:8090/jquery-1.10.1.js 可以正常返回,并且此时进入设置的缓存目录会发现里面有一个缓存好的文件。

cd /usr/local/proxy_cache
tree

为了更方便的看到配置的缓存是否生效,可以在nginx配置中追加配置 add_header nginx-cache "$upstream_cache_status"; 向浏览器响应头中添加一个参数nginx-cache来确定,值为HIT时说明命中了缓存,请求的结果来源于nginx的缓存,如果值为MISS,说明没有使用缓存的数据。

第一次访问 http://190.118.52.56:8090/jquery-1.10.1.js nginx-cache值为MISS,当再次访问的时候值就为HIT了。

实在不放心,可以把tomcat停掉,访问还是一样会返回数据。

清除缓存

我们可以直接将/usr/local/proxy_cache缓存目录下的文件删除,或者可以通过添加ngx_cache_purge模块来清楚缓存。

安装ngx_cache_purge模块

下载

从官网下载安装包 点此去下载  然后上传到/usr/local目录下。

解压

tar -zxf ngx_cache_purge-2.3.tar.gz

使用 nginx -V 查看nginx已有配置:

进入Nginx的安装目录,使用./configure进行参数配置,之前我已经安装过--with-http_ssl_module --with-stream,在执行configure时不要漏掉:

cd nginx-1.20.1
./configure --with-http_ssl_module --with-stream --add-module=/root/nginx/module/purge

使用make进行编译:

make

备份sbin目录下的nginx文件:

mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginxold

将编译后的objs中的nginx拷贝到nginx的sbin目录下:

cp objs/nginx /usr/local/nginx/sbin

使用make upgrade进行升级:

make upgrade

如果执行make upgrade的时候报如下错误:

只要指定nginx配置文件的方式重新启动后再执行upgrade就可以了,如下:

/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf

执行 nginx -V 可以查看是否安装成功:

nginx配置并测试

在nginx的配置文件中追加如下配置:

location ~/purge(/.*) {
    proxy_cache_purge yjh $scheme$proxy_host$request_uri; # 参数: 缓存名称 key
}

缓存名称与上面配置的一致,key上面使用的默认配置,这里保持一致也用$scheme$proxy_host$request_uri。

访问 http://190.118.52.56:8090/purge/juqery-1.10.1.js 清除缓存的js文件,结果却404,如下:

 

原因在于 访问 http://190.118.52.56:8090/jquery-1.10.1.js 和 访问 http://190.118.52.56:8090/purge/jquery-1.10.1.js 实际访问的是两个地址,所以后面的访问会404。我们可以通过配置日志的方式记录实际访问的地址到日志文件,实际打印的地址如下:

我们把proxy_cache_key的值以及使用到的地方不再使用默认值,比如改为yjh,完整配置如下:

    proxy_cache_path /usr/local/proxy_cache levels=2:1 keys_zone=yjh:200m inactive=1d max_size=20g;
    log_format myformat $scheme$proxy_host$request_uri;
    upstream backend{
        server localhost:8080;
    }
    server {
        listen 8090;
        server_name localhost;
        location / {
                access_log logs/access.log myformat;
                proxy_cache yjh;
                proxy_cache_key yjh;
                proxy_cache_valid 200 5d;
                proxy_pass http://backend/js/;
                add_header nginx-cache "$upstream_cache_status";
        }
       location ~/purge(/.*) {
                access_log logs/access.log myformat;
                proxy_cache_purge yjh yjh;
       }
    }

 重启nginx后,再次访问 http://190.118.52.56:8090/purge/jquery-1.10.1.js 就会成功的清楚nginx的web缓存,清除后再次访问 http://1190.118.52.56:8090/jquery-1.10.1.js 查看浏览器header时就会发现 nginx-cacha的值变为了MISS,说明没有使用缓存的数据。

 

 

设置不缓存的数据

比如说对于一些经常发生变化的数据。如果进行缓存的话,就很容易出现用户访问到的数据不是服务器真实的数据。所以对于这些资源我们在缓存的过程中就需要进行过滤,不进行缓存。

相关指令

proxy_no_cache

该指令是用来定义不将数据进行缓存的条件。

语法proxy_no_cache string ...;
默认值
位置http、server、location

proxy_cache_bypass

该指令是用来设置不从缓存中获取数据的条件。

语法proxy_cache_bypass string ...;
默认值
位置http、server、location

上述两个指令都有一个指定的条件,这个条件可以是多个,并且多个条件中至少有一个不为空且不等于"0",则条件满足成立。只有条件成立时,配置才生效。

常用的配置参数有以下三个,参数及代表的含义如下:

$cookie_nocache
指的是当前请求的cookie中键的名称为nocache对应的值。
$arg_nocache和$arg_comment
指的是当前请求的参数中属性名为nocache和comment对应的属性值。

测试

我在nginx配置文件中,追加 proxy_no_cache 配置,如下:

proxy_no_cache 1;

此时不管我们访问多少次 缓存目录 /usr/local/proxy_cache 中不会再有缓存数据,浏览器的nginx-cache值始终为MISS,说明设置的proxy_no_cache生效。

上面只是简单的设置了proxy_no_cache为1,把所有的请求都不进行缓存,这样肯定是不合适的,通常我们会设置多个参数,比如上面提到的$nocache $cookie_nocache $arg_nocache $arg_comment 这三个参数,另外如果相对特定资源不进行缓存,还是以这个js文件为例,想让js文件不缓存,可以单独再追加一个判断条件,如果是js文件,我们就在peoxy_no_cache参数后面追加一个不为零且不为空的值,使其生效,比如下面这样配置:

    proxy_cache_path /usr/local/proxy_cache levels=2:1 keys_zone=yjh:200m inactive=1d max_size=20g;
    log_format myformat $scheme$proxy_host$request_uri;
    upstream backend{
        server localhost:8080;
    }
    server {
        listen 8090;
        server_name localhost;
        location / {
                if ($request_uri ~ /.*\.js$){
                    set $mynocache 1;
                }
                access_log logs/access.log myformat;
                proxy_cache yjh;
                proxy_cache_key yjh;
                proxy_cache_valid 200 5d;
                proxy_pass http://backend/js/;
                add_header nginx-cache "$upstream_cache_status";
                #proxy_no_cache 1;
                proxy_no_cache $cookie_nocache $arg_nocache $arg_comment $mynocache;
        }
       location ~/purge(/.*) {
                access_log logs/access.log myformat;
                proxy_cache_purge yjh yjh;
       }
    }

如上,我们在location块中追加了一个判断条件,使用正则表达式匹配访问路径,当访问的为js时,设置变量mynocache的值为1,并且将mynocache的值连通另外三个参数一起设置到peoxy_no_cache中,这样的好处是,既可以通过正则表达式拦截请求使特定的资源类型不进行缓存,又保持了灵活性,使我们可以通过浏览器或者后台发送请求的时候,在任意路径上通过添加nocache或comment 来设置哪些资源不时进行缓存。

清空/usr/local/proxy_cache目录下缓存的文件,我们重启nginx,多次访问  http://190.118.52.56:8090/jquery-1.10.1.js 发现/usr/local/proxy_cache目录下没有缓存的文件。

我们再试下从浏览器中追加参数的方式,多次访问 http://190.118.52.56:8090/jquery-1.10.1.js?nocache=1 发现/usr/local/proxy_cache目录下还是没有缓存的文件。说明配置不缓存生效。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐