一篇文章教会你Nginx缓存,Be a king of caching

Nginx配置缓存

Be a king of caching

今天我将向您展示如何使互联网更快更稳定。如何轻松适应Nginx的缓存,以提升您的应用程序。

缓存概念

在我们开始之前,我需要做一个先验假设。即内容是准实时的。这意味着我们的数据或您希望我们的HTTP响应,不要经常更改。请注意,“不经常”这个短语并不是一个严格的定义。它可以是1秒,1小时,1周等。

好吧,考虑到这一点,让我们从最初的情况开始,不涉及缓存,看起来像这样。
这里写图片描述
用户向应用程序发出请求并获得响应。
这里写图片描述

在此方案中添加缓存是提高性能,容量和可用性的简单方法。它的工作原理是将服务器或应用程序的响应保存到本地存储或内存。

让我们考虑一下这种简单的情况。客户端像上一个示例一样向应用程序发出请求,但这次他通过缓存。
这里写图片描述

应用程序响应和缓存会将此响应转发给客户端,但它也会将其保存在本地。
这里写图片描述

下次用户执行相同的请求时,缓存会检查它是否已有此信息。
这里写图片描述

如果是这种情况,它会通过提供此缓存内容立即响应用户。

Nginx缓存:缓存介绍第二个响应

请注意,第二个请求根本不涉及申请。

缓存增加了系统的复杂性,但它带来了很多好处

  • 它提高了网站性能 - 请求不必经历整个渲染过程
  • 它通过减少原始服务器的负载来增加容量
  • 它还提供更高的可用性 - 通过在原始服务器关闭时提供陈旧内容

在我们开始使用Nginx之前,我想提一下缓存内容的替代方法。Squid Cache和Varnish Cache是我最喜欢的例子。我在职业生涯中看到的标准用例如下:

Nginx缓存:在本地缓存替代品

您只需将缓存放在HTTP服务器前面。在应用程序服务器上或在专用机器上:

Nginx缓存:缓存替代品清漆负载均衡器

这显然增加了系统的复杂性,但它可能更适合您的情况。阅读,比较功能并做出决定。

在这篇文章中,我们将只关注Nginx。


使用Nginx进行缓存

Nginx是一个HTTP服务器,它非常适合提供静态文件和代理请求。由于其异步性质,它具有轻量级资源利用率。

在缓存方面,Nginx集成了:

  • HTTP服务器
  • FastCGI的
  • uwsgi
  • SCGI
    现在我们知道缓存如何工作以及Nginx是什么。我们来看看Nginx的缓存实现。

一个例子应该说清楚。首先,客户端提出请求。

Nginx缓存:HTTP请求可视化示例

示例HTTP请求如下图所示:

这里写图片描述
基于它的一些细节,Nginx生成一个哈希键。

Nginx缓存:如何创建缓存密钥

现在Nginx检查内存中是否已存在此哈希键。如果没有,请求将转到应用程序。

Nginx缓存:

应用程序应答并将其响应保存到文件系统。

Nginx缓存:

此外,先前生成的哈希密钥将保存到内存中。为了便于理解,我将散列键值与保存文件的位置一起可视化。但请记住,Nginx只在内存中存储哈希键。

Nginx缓存:

最后,用户得到了回复。

Nginx缓存:

当我们的客户端第二次请求相同的URL时,Nginx再次生成散列密钥并检查它是否存在于内存中。这次它就在那里,所以Nginx从与散列键相关联的文件系统提供缓存文件。

Nginx缓存:

请注意,第二个请求根本不涉及申请。

对于第二个请求,客户端不会等待应用程序首先从数据库中获取数据,然后呈现页面。相反,Nginx提供具有缓存版本响应的静态文件。

此外,这些文件很可能缓存在内存中。这次不是由Nginx(尽管它给操作系统提供了一些提示)而是由操作系统提供的。使用尽可能高效的资源是Linux的属性。这使得从文件系统中读取文件非常快。


配置 - 可用指令

现在我们已经了解了Nginx缓存如何工作的技术背景,让我们看看我们如何配置它。

首先在http关卡中我们定义数据的存储位置。我们在文件系统和内存区域及其大小上指定路径。该内存区储存唯一元哈希键-对缓存的项目的信息。

注意

每个项目都占用大约0.125 kB内存,因此我们可以存储大量内存。在1MB例如Nginx的可以存储大约8000缓存键

基本

基本缓存定义如下所示:

proxy_cache_path /data/nginx/cache keys_zone=zone_name_one:10m;

要启用它,我们只需使用该proxy_cache指令。

proxy_cache zone_name_one;

也可以通过添加max_size参数来限制用于存储缓存内容的文件系统的大小。

proxy_cache_path /data/nginx/cache keys_zone=one:10m max_size=200m;

然后,我们还可以选择何时在特定时间内不使用文件时(从缓存中删除文件)。

proxy_cache_path /data/nginx/cache keys_zone=one:10m inactive=60m;

还有一个很好的小参数,让我们定义缓存的层次结构级别。

proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=one:10m;

下图说明了层次结构级别配置:

Nginx缓存:proxy_cache_path级别示例

现在让我们看看你是否正确理解它。准备好测验?根据下图,level参数应该是什么?

Nginx缓存:proxy_cache_path级别示例

答案是2:4,如果我们看一下下面的图像就更清楚了:

Nginx缓存:proxy_cache_path级别示例


什么/何时缓存?

默认情况下,Nginx仅缓存GETHEAD请求。您可以使用proxy_cache_methods指令更改此设置:

proxy_cache_methods GET HEAD POST;

您还可以指示Nginx仅在请求响应至少5次后才缓存响应。

proxy_cache_min_uses 5;

这在您拥有大量内容的情况下非常有用,但您只想缓存那些非常受欢迎的请求。

Nginx也可以为我们节省上行带宽和磁盘写入。通过尊重缓存标头和304, not modified响应,如果启用以下指令,Nginx将不会再次下载内容:

proxy_cache_revalidate on;

如何缓存?

使用Nginx,我们不限于通过相同的规则缓存所有内容。相反,我们可以告诉Nginx应该使用哪些信息来生成散列密钥。我们可以做到这一点的httpserver或者location水平。以下是两个例子:

proxy_cache_key "$host$request_uri$cookie_user";
proxy_cache_key "$scheme$proxy_host$uri$is_args$args";

我们也可以告诉Nginx,在哪些情况下请求不应该存储在缓存中

proxy_no_cache $http_pragma $http_authorization $cookie_nocache $arg_nocache;

缓存多长时间?

有一个简单的指令告诉Nginx缓存某种类型的响应多长时间:

proxy_cache_valid any      1m;
proxy_cache_valid 200 302 10m;

但主要是源服务器的头部定义了内容的可缓存性:

  • 过期
  • 缓存控制
  • X-Accel-Expires - Nginx特殊标题。
    覆盖其他标头。当您需要向客户端提供不同的标头时使用。

上述选项的优先级如下图所示,最重要的是:
这里写图片描述


其他

以下选项为可用性因素增加了很多。当应用程序响应超时或返回50x状态代码时,它允许Nginx提供过时(旧的,过期的)内容:

proxy_cache_use_stale error timeout;

另一个很酷的功能是只允许第一个请求通过应用程序。这可以通过以下方式启用:

proxy_cache_lock on;

您已经知道,原始返回的内容将流式传输到磁盘。默认情况下,proxy_cache_path指令中定义的位置。您还可以将这些文件存储在临时目录中,然后再将其移动到缓存路径。如果您需要此行为,请使用此:

proxy_temp_path /tmp/custom_cache/;

该指令适用于多个缓存。但请记住,它的效率始终低于临时路径与缓存路径相同的效率


调试Nginx的缓存

我认为以正确的方式调试任何软件比实际了解软件本身更重要。良好的调试过程可确保更好地理解,最重要的是,可以非常快速地解决难题。

在本章中,我将向您展示轻松调试Nginx缓存的一些技巧。

第一个技巧是绕过缓存。

proxy_cache_bypass $arg_nocache $cookie_nocache $arg_comment;

上面的指令允许您指定何时省略缓存。这意味着带有nocache=true查询参数的每个请求都会转到原点。甚至可能是Nginx也会缓存结果。

另一个技巧是添加包含缓存状态信息的标头。您只需添加标题即可:

add_header X-Cache-Status $upstream_cache_status;

或者以下面介绍的更复杂的方式,它只允许本地请求查看标题:

map $remote_addr $cache_status {
    127.0.0.1 $upstream_cache_status;
    default "";
}
...
add_header X-Cache-Status $cache_status;

通过调试X-Cache-Status标题,您将欣赏下表:

--
MISSObject was not found in the cache. Response was served from the origin. Response may have been saved to cache.
BYPASSGot response from upstream. Response may have been saved to cache.
EXPIREDCached object has expired. Response was served from the upstream.
STALEObject served from cache because of issues with origin server response
UPDATINGServe stale content from cache because proxy_cache_lock has timed out and proxy_use_stale takes controll
REVALIDATEDproxy_cache_revalidate verified that the current cached content was still valid
HITThe object was found in the cache and it is served from there

在接下来的两章中,我们将了解维护缓存文件涉及哪些进程。在我们开始讨论很酷的例子后,这些章节非常简短。所以和我在一起!


缓存加载器

Nginx缓存加载器是一个负责从磁盘加载缓存的进程。

它只运行一次(启动时)并将元数据加载到内存区域。它在迭代中运行,直到加载所有键。

我们可以使用以下选项调整它的行为(以正确的方式利用CPU):

  • loader_threshold - 一个迭代时间有多长
  • loader_files - 不要加载更多的物品
  • loader_sleeps - 迭代之间的暂停时间

下面给出一个例子:

proxy_cache_path /data/nginx/cache keys_zone=one:10m [loader_files=number] [loader_sleep=time] [loader_threshold=time];

下面的漫画显示缓存加载器仅在启动时使用,并且它在由所描述的参数定义的迭代中工作。
这里写图片描述


缓存管理器

Nginx缓存管理器是一个随时间清除缓存的过程。

如果文件大小超过,它会定期检查文件存储并删除最近最少使用的数据max_size。它还会删除未独立于缓存设置使用的文件。

观看下面的漫画,其中说明了缓存管理器职责
这里写图片描述


两个实例

例子一

upstream backend {
    server 127.0.0.1:8001;
    server 127.0.0.1:8002;
    server 127.0.0.1:8003;
}

#代理缓存空间
#levels:缓存文件按照两层目录进行分级保存
#keys_zone:定义这个空间的名字,10m为这个空间的大小(一般1m可以存放8000个key)
#max_size:这个缓存空间的最大空间,满了会触发淘汰规则进行处理
#inactive:不活跃时间 表示在60分钟内,如果该缓存文件没被访问,会把它清理掉
#use_temp_path:临时文件,建议关闭。
proxy_cache_path /opt/site/cache levels=1:2 keys_zone=sam_cache:10m max_size=10g inactive=60m use_temp_path=off;

server {
    listen       80;
    server_name  localhost www.sam.com;

    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;

    #匹配uri,如果uri为 /login 或 /register 或 /password/reset,添加变量$cookie_nocache 值为1
    if ($request_uri ~ ^/(login|register|password\/reset)){
        set $cookie_nocache 1;
    }

    location / {
        proxy_pass http://backend;

        proxy_cache sam_cache;                  #使用前面定义的proxy_cache_path
        proxy_cache_valid 200 304 12h;          #设置200和304过期时间为12h
        proxy_cache_valid any 10m;              #其他过期时间为10分钟
        proxy_cache_key $host$uri$is_args$args; #修改缓存纬度,缓存的key
        add_header Nginx-Cache "$upstream_cache_status";

        #配置不缓存的,如果上面条件判断中有新增变量$cookie_nocache,那么对应请求不进行缓存
        proxy_no_cache $cookie_nocache;

        #当命中的服务器出现错误、超时、请求头不完整、500、502、503时,会跳过这一台服务器去访问下一台服务器。
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;

        ###### 以下是代理常规配置 ######
        proxy_redirect default; #一般配置默认即可

        #添加头信息
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;

        #配置超时
        proxy_connect_timeout 30;
        proxy_send_timeout 60;
        proxy_read_timeout 60;

        #配置缓冲区,
        proxy_buffer_size 32k;
        proxy_buffering on;
        proxy_buffers 4 128k;
        proxy_busy_buffers_size 256k;
        proxy_max_temp_file_size 256k;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

}

例子二

# proxy_cache_path 缓存的基本配置,需要放在 server 的外面,下面是配置项
# 缓存文件路径:/data/nginx/cache(自定义)
# keys_zone 设置缓存名字和共享内存大小 one-cache:50m
# levels 设置缓存文件目录层次;levels=1:2 表示两级目录
# inactive 删除指定时间内未被访问的缓存文件
# max_size 缓存硬盘空间最多为 200m,如果缓存空间满,默认覆盖掉缓存时间最长的资源。

# 下面两项是 nginx 启动时加载缓存的参数
# loader_threshold 加载器每次迭代过程最多执行300毫秒
# loader_files 加载器每次迭代过程中最多加载200个文件



proxy_cache_path /data/nginx/cache keys_zone=one-cache:50m levels=1:2 
                 inactive=7d loader_threshold=300 loader_files=200 max_size=200m;

#百度语音识别接口跨域代理
server {
    listen 80;
    server_name  vop-baidu.proxy.abc.com;


    add_header Access-Control-Allow-Origin *; 
    add_header Access-Control-Allow-Headers X-Requested-With,content-type;
    add_header Access-Control-Allow-Methods GET,POST; #,OPTIONS;
    add_header Access-Control-Max-Age 99999999;

    location / {
        proxy_pass  http://vop.baidu.com;

   }

   #百度语音 token
   location /token {

                proxy_cache one-cache; # 使用名称为one-cache的缓存(必须)
                proxy_cache_methods GET HEAD POST; #配置需要缓存的方法 默认GET|HEAD
                proxy_cache_valid 200 302 10d; # 对200和302状态的请求缓存10天,any 表示所有状态
                proxy_cache_key $uri; # 定义缓存key 默认是请求URL

                #****很重要*** 此项适用于配置要忽略的proxy_pass目标服务器的响应 header 项,
                #当目标服务器设置了 Cache-Control或Set-Cookie header等项时 则响应
                #不会被缓存或影响缓存策略,所以这里选择忽略
                proxy_ignore_headers Cache-Control Set-Cookie; 

                proxy_pass  https://openapi.baidu.com/oauth/2.0/token?xxxxxxx;
        }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值