Nginx缓存

Posted Lazyball

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Nginx缓存相关的知识,希望对你有一定的参考价值。

借鉴自网络 https://t.hao0.me/nginx/2015/02/17/nginx-content-caching.html  并非原创 尊重原创

本文将讲述如何使用NGINX缓存。NGINX缓存可以将后端服务器的响应保存在磁盘上,当客户端发来请求时, 会直接使用缓存来响应客户端,而不会去请求后端服务器。

开启缓存

为了开启缓存,可以在http上下文中使用proxy_cache_path, 然后在你想启用缓存的地方加上proxy_cache,如

http {
    ...
    proxy_cache_path /data/nginx/cache keys_zone=one:10m;

    server {
        proxy_cache one;
        location / {
            proxy_pass http://localhost:8000;
        }
    }

1. proxy_cache_path指令只能在http上下文中使用。
2. proxy_cache_path指令需要两个必要的参数:path(缓存的存储路径)和keys_zone(共享内存区name:size, name对应proxy_cache指令的参数)。
3. 共享内存区用于存储缓存项的元数据信息,它的大小并不会限制缓存的总大小,缓存本身同其元数据信息一起被保存在文件系统特定的文件里,你可以通过max_size限制文件存储的大小,然而 实际的文件存储可以暂时超过该值,直到一个叫cache manager的进程检查缓存大小,进而移除掉最近最少使用的缓存及其元数据。

缓存进程

NGINX缓存中有两个额外的NGINX进程:cache loader和cache manager。

cache manager会被周期性地激活,并检查缓存文件存储的状态。实际上,当文件存储大小超过 max_size时,cache manager会移除掉最近最少使用的数据。

cache loader只会在NGINX启动后被激活一次,它加载之前缓存数据的元信息到共享内存区中。 一次性加载整个缓存可能会消耗很多资源,并且刚开始会降低NGINX的性能。这就是为什么cache loader会使用 proxy_cache_path的配置进行迭代工作,每一次迭代持续不超过loader_threshold(默认200)毫秒,每一次迭代加载不超过loader_files(默认100)缓存项, 迭代之间的间隔时间设置为loader_sleeps(默认为50)毫秒。

如下面的配置将加快缓存元数据加载

proxy_cache_path /data/nginx/cache keys_zone=one:10m
loader_threshold=300 loader_files=200;
        

指定哪些请求需要缓存

默认情况下,nginx会缓存所有来自后端服务器第一次响应GET和HEAD请求的响应数据。NGINX使用请求字符串作为请求标识符。 无论什么时候,两个具有相同标识符的请求都被认为是相同的,于是相同的缓存响应将被发送给客户端。 proxy_cache_key指令可以用来指定请求标识符的计算方法

proxy_cache_key "$host$request_uri$cookie_user";

我们可以使用proxy_cache_min_uses设置响应被缓存的最小请求次数。(默认为1,即请求1次就被缓存)

proxy_cache_min_uses 5;
        

我们也可以增加额外要缓存的HTTP请求方法

proxy_cache_methods GET HEAD POST;

限制或绕过缓存

默认情况下,响应被缓存的时间是没有限制的。当文件缓存大小超出 max_size时,最近最少使用的缓存项将被移除。否则,缓存的响应将被永久保存。

我们可以通过proxy_cache_valid来设置特定状态码的缓存有效时间

proxy_cache_valid 200 302 10m; # 200, 302状态的响应将被缓存10分钟
proxy_cache_valid 404      1m; # 404状态的响应将被缓存1分钟
        

也可以统一设置缓存时间

proxy_cache_valid any 5m;

为了使响应不从缓存中抓取(即使缓存中存在),我们可以使用proxy_cache_bypass定义一些条件。 默认情况下,是没有任何条件的。该指令有1个或多个参数,可由多个变量组成,如果至少一个字符串条件非空而且非“0”,nginx就不会从缓存中去取响应。

proxy_cache_bypass $cookie_nocache $arg_nocache$arg_comment;
        

同样可以使用proxy_no_cache来禁止响应被缓存,用法同proxy_cache_bypass

proxy_no_cache $http_pragma $http_authorization;

完整的配置列子

http {
    ...
    proxy_cache_path /data/nginx/cache keys_zone=one:10m loader_threshold=300 loader_files=200 max_size=200m;


    upstream backend1 {
        server localhost:8080;
    }

    upstream backend2 {
        server localhost:8090;
    }

    server {
        listen 80;
        proxy_cache one;

        location / {
            proxy_pass http://backend1;
        }

        location /some/path {
            proxy_cache_valid any   1m;
            proxy_cache_min_uses 3;
            proxy_cache_bypass $cookie_nocache $arg_nocache$arg_comment;
            proxy_pass http://backend2;
        }
    }
}
        

1. 后端服务器backend1返回的响应会在第一次被请求就缓存,并且缓存尽量长时间。
2. 后端服务器backend2可能数据变化较大,所有数据仅缓存1分钟,且当同一请求达到3次,其响应才被缓存,且进行一些缓存绕过设置。

以上是关于Nginx缓存的主要内容,如果未能解决你的问题,请参考以下文章

Swift新async/await并发中利用Task防止指定代码片段执行的数据竞争(Data Race)问题

Swift新async/await并发中利用Task防止指定代码片段执行的数据竞争(Data Race)问题

如何缓存片段视图

phalcon: 缓存片段,文件缓存,memcache缓存

更改代码时出现 Django、Nginx、FastCGI 缓存问题

在每个用户的Rails中使用片段缓存