最近我听说Nginx已将缓存添加到其反向代理功能中。我环顾四周,但找不到更多信息。

我想将Nginx设置为Apache / Django前面的缓存反向代理:要求某些(但不是全部)具有Nginx代理请求)动态页面到Apache,然后将生成的页面缓存起来,并从缓存中为这些页面提供后续请求。

理想情况下,我想以两种方式使缓存无效:


在缓存的项目上设置到期日期
要显式使缓存的项目无效。例如。如果我的Django后端已更新某些数据,我想告诉Nginx使受影响的页面的缓存无效

是否可以设置Nginx来做到这一点?怎么样?

评论

未经测试,但来自gumroad.com/l/ngx_purge:“ ngx_purge是Nginx的纯Lua模块,允许用户从nginx缓存中清除对象。”。

#1 楼

我不认为有一种方法可以使缓存的项目显式无效,但是这里有一个示例,说明如何进行其余操作。更新:正如Piotr在另一个答案中提到的那样,您可以使用一个缓存清除模块。您还可以使用nginx的proxy_cache_bypass强制刷新缓存的项目-有关更多信息,请参见Cherian的答案。

在此配置中,将从example.net中检索并存储未缓存的项目。缓存的版本将提供给将来的客户端,直到它们不再有效(60分钟)为止。

您的Cache-Control和Expires HTTP标头将被接受,因此,如果要显式设置到期时间日期,您可以通过在要代理的内容中设置正确的标头来做到这一点。

您可以调整很多参数-有关所有这些的更多信息,请参见nginx代理模块文档。有关不同设置/参数含义的详细信息:
http://nginx.org/r/proxy_cache_path

http {
  proxy_cache_path  /var/www/cache levels=1:2 keys_zone=my-cache:8m max_size=1000m inactive=600m;
  proxy_temp_path /var/www/cache/tmp; 


  server {
    location / {
      proxy_pass http://example.net;
      proxy_cache my-cache;
      proxy_cache_valid  200 302  60m;
      proxy_cache_valid  404      1m;
    }
  }
}


评论


对于没有20k / req / s的新应用,这是一个合理的第一步。

–user31170
2011年5月2日,13:05

@Barry第二个步骤是什么?

–于尔根·保罗(JürgenPaul)
2012年5月31日0:52

@Legit-我不知道,但是传统上最后一步是“ Profit” :-)

– Stephen C
2012年7月17日在7:30

可悲的是,它不适用于nginx 1.11。由于上一次更新大约是3年前,因此看来这不再是解决方案。

–izogfif
17年11月22日在11:05

inactive = 600m是什么意思?不活跃不是应该时间吗? `[无效=时间]

–NeverEndingQueue
18年11月2日在15:01



#2 楼

您可以通过

proxy_cache_bypass       
专门使已缓存的页面无效,例如,要缓存页面,以这种方式设置缓存

location = /pageid {
  proxy_pass http://localhost:82;
  proxy_set_header   Host             $host;
  proxy_set_header   X-Real-IP        $remote_addr;
  proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
  proxy_ignore_headers Set-Cookie; 
  proxy_ignore_headers Cache-Control; 
  proxy_cache_bypass        $http_secret_header;
  add_header X-Cache-Status $upstream_cache_status;
}


现在,当您要使该页面无效并再次缓存时

用标头进行秘密的curl调用

curl "www.site.com/pageid" -s -I -H "secret_header:true" 


它将使其无效并缓存。

从nginx 0.7开始工作。

作为补充,add_header X-Cache-Status可用于检查页面是否来自缓存。

评论


这也只能在新页面也可缓存时更新缓存的页面。如果您删除了一个页面(后端现在提供了404或其他错误),该页面现在将发送Set-Cookie或“ Content-Control:private”标头,则缓存的内容将不会“无效”。

– rbu
16年1月27日在14:25

#3 楼

我建议您尝试一下Varnish。 Varnish特别设计为反向代理缓存。它将兑现您从原始服务器发送的满足您第一个请求的所有缓存控制标头。

对于第二个请求,显式无效。我的强烈建议是通过重命名文件或使用某种形式的查询字符串缓存无效化程序来更改您想要使资源无效的URL的名称。 Varnish确实有一个PURGE操作,它将从Varnish的缓存中删除资源,但不会让您控制您和用户之间的任何其他缓存。正如您所说的,您要明确清除资源,那么标准的http控件标头将无济于事。在这种情况下,破坏资源缓存的最简单方法是重命名资源。

评论


您能否解释一下“重新命名文件或使用某种形式的查询字符串缓存破坏程序”是什么意思?我不确定我是否理解为什么使用像PURGE这样的操作不是一个好主意。

–继续
09年6月24日在15:54

+1清漆。在工作中使用正确的工具总会更好。

–汤姆·奥康纳(Tom O'Connor)
09年11月17日在11:53

@以下:在性能和多功能性领域几乎没有希望接触清漆。这由FreeBSD领先的内核开发人员之一和欧洲的专门团队支持。 Twitter,heroku等公司都在生产Varnish。

–user31170
2011年5月2日,12:59



缓存无效化器的最简单示例是将查询字符串中的版本号附加到静态资源,因此style.css变为style.css?123。当您要推送文件的新版本时,请将资源的URL更改为style.css?124,现在缓存会将其拾取为全新资源,以单独缓存。 Apache将为文件style.css提供附加的查询字符串,因此不需要更改实际文件。

–chmac
2012年4月20日12:27



如果可能的话,最好将缓存破坏符放入文件名本身,例如style.v123.css,因为某些缓存不会缓存具有查询字符串的请求。

–诺亚·麦克里斯(Noah McIlraith)
2012年7月29日15:34

#4 楼

大多数缓存工具(Citrix)允许强制刷新(Ctrl + r)重新填充缓存的页面。

这是我发现在nginx中执行类似操作的一个技巧。

server  {
        # Other settings
        proxy_pass_header       Set-Cookie; # I want to cache logged-in users
        proxy_ignore_headers    X-Accel-Redirect;
        proxy_ignore_headers    X-Accel-Expires Expires Cache-Control;
        if ($http_cache_control ~ "max-age=0") {set $eac 1;}
        proxy_cache_bypass $eac;
}


这假设您在浏览器中执行Ctrl + r时,Cache-Control标头在其请求中具有max-age = 0。我知道Chrome可以做到这一点,但是我没有在其他浏览器中尝试过。通过仅添加更多将$eac变量设置为1的if语句,可以添加更多的标头字段很容易。

#5 楼

要使选定的页面无效,您可以对nginx-0.8.x使用“ cache_purge”补丁,它确实可以满足您的需求;)

可在此处使用。

#6 楼

缓存是nginx中的一个相当新的功能(目前尚不完善),但足够稳定,可以在生产中使用。


使用英文文档
在邮件列表中询问
使用Google Translate等翻译俄语文档
使用清漆


#7 楼

我相信NginxHttpProxyModule能够缓存HTTP请求。查找以以下内容开头的指令:

proxy_cache


是的,可以通过以下指令来控制缓存行为:

proxy_cache_valid


#8 楼

基于您找不到有关它的文档这一事实,我会有点警惕在生产中依赖它。您是否考虑过Varnish?这是我的“反向代理nginx”,小巧,轻巧,能出色地完成一项工作。

评论


文档在这里:wiki.nginx.org/NginxHttpProxyModule#proxy_cache

– rmalayter
2010年9月9日4:00

#9 楼

如果在应用程序上使用eTag并将nginx放在它的前面,则它将为您处理过期,因为如果eTag更改,它将使缓存无效。

评论


真?好像ngnix与etag匹配,并且从不与应用程序对话以查找是否有更新的etag。

–约翰·内格勒(John Naegle)
2013年6月26日18:55

#10 楼

您可以使用多个指令/参数来控制Nginx的缓存过期:


proxy_cache_valid 200 302 10m;
添加以下HTTP标头之一(优先级很重要-请参阅我的博客文章):


Expires
Cache-Control
X-Accel-Expires



inactive指令中的proxy_cache_path参数:

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


如果您想了解有关Nginx缓存的更多信息,我推荐我的博客文章。

清除主题确实很有趣,因为此功能仅存在在Nginx Plus(Nginx的商业版)中。我真的很喜欢@ randy-wallace的答案。但是还有其他可能性,例如ngx_cache_purge模块。

您可以做的最简单的操作是手动删除缓存的文件:



生成您的哈希键:

echo -n ‘httpczerasz.com/time.php’ | md5sum



从文件系统中删除文件:

rm /data/nginx/cache/1/27/2bba799df783554d8402137ca199a271




#11 楼

对于未来的访问者:同时,nginx反向代理已集成了缓存,并且可以在以下位置获取文档:


https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache


语法:proxy_cache zone | off;

默认值:proxy_cache off;

上下文:http,服务器,位置

定义用于缓存的共享内存区域。同一区域可以在多个地方使用。参数值可以包含变量(1.7.9)。 off参数禁用从先前配置级别继承的缓存。


评论


嗨,塔里克(Tarik),这个问题非常具体地说明了需要实现的目标,这超出了“仅启用缓存”的范围。

– asdmin
19年3月1日在7:28

#12 楼

fastcgi_cache_path  /opt/nginx-cache  levels=2:2   keys_zone=img:50m;

    location /img/ {
        fastcgi_pass $backend;
        include fcgi_params;
        fastcgi_intercept_errors off;   
        fastcgi_cache_key $server_addr$request_uri;       
        fastcgi_cache img;
        fastcgi_cache_valid any 1m;
        fastcgi_hide_header Set-Cookie;
    }


这将为/ img /位置创建缓存。它在/ opt / nginx-cache中。对象将被缓存1分钟。

您可以编写不同的响应代码,而不必编写任何响应代码。

现在您不能使所选页面的缓存无效。也许在0.8.x中是可能的。

评论


最初的问题是关于在Apache前面使用nginx,而不是在nginx处理的fastcgi应用程序前面使用。

– Graham Dumpleton
09年7月13日在1:52

#13 楼

有一个名为ncache的nginx插件,该插件声称是“基于nginx Web服务器的Web缓存系统。比squid更快,更高效。”