如何清除nginx的缓存?

310

我使用nginx作为前端服务器,我已经修改了CSS文件,但nginx仍然提供旧的文件。

我尝试重新启动nginx,但没有成功,并且我搜索了谷歌,但没有找到有效的清除方法。

一些文章说我们可以删除缓存目录:var/cache/nginx,但是在我的服务器上没有这样的目录。

现在我该怎么办?


1
您的Nginx配置的更多细节将非常有帮助。您是否正在使用proxy_cache - Alexander Azarov
5
Nginx 默认不进行缓存。 - Alexander Azarov
30
你是否在使用虚拟机软件,比如VirtualBox或Vagrant?如果是的话,尝试关闭sendfile功能,因为它们无法很好地兼容。 - kolbyjack
9
你确定缓存是在nginx这一侧吗?你使用curl这样的工具验证了行为吗?通常情况下,像这样的问题只是客户端缓存没有请求更新的资源,因为它被告知旧资源将在很长一段时间内有效,例如通过expires max或类似方式。 - kolbyjack
@kolbyjack 那么我应该在实际服务器上保留sendfile,但在virtualbox/vagrant vm上关闭它吗?还是我应该始终将其关闭? - Kim Stacks
显示剩余4条评论
25个回答

202
我遇到了完全相同的问题 - 我正在Virtualbox中运行我的nginx。我没有启用缓存。但是看起来sendfilenginx.conf中设置为on,这就引起了问题。@kolbyjack在评论中提到了这一点。
当我关闭sendfile时,它可以正常工作。 这是因为:

Sendfile用于“在一个文件描述符和另一个文件描述符之间复制数据”,而显然在虚拟机环境下或者至少通过Virtualbox运行时会有一些麻烦。在nginx中关闭此配置将以不同的方法提供静态文件,您的更改将立即且无需疑问地反映出来。

这与此错误相关: https://www.virtualbox.org/ticket/12597

7
请参考这个链接:http://jeremyfelt.com/code/2013/01/08/clear-nginx-cache-in-vagrant/ 该链接介绍了如何在Vagrant中清除Nginx缓存的方法。 - Sian Lerk Lau
在我的情况下,替代解决方法是为这些文件类型打开gzip。无论哪种方式,问题都得到了解决。 - Dingle
3
我使用以下命令:'sudo vim /etc/nginx/nginx.conf',将 'sendfile on' 改为 'sendfile off'。 - Koray Güclü
22
我关闭了sendfile,但没有成功。 - marukobotto
关闭了sendfile,更改立即生效。运行在Amazon EC虚拟实例上。虽然希望保持此设置... - Didzis
显示剩余2条评论

149

你也可以通过逐个文件地绕过/重新缓存文件来实现

proxy_cache_bypass $http_secret_header;

另外,你可以返回此标题以检查是否从缓存中获取它(将返回“HIT”),还是从内容服务器获取它(将返回“BYPASS”)。

add_header X-Cache-Status $upstream_cache_status;

要使缓存的文件过期/刷新,请使用curl或任何REST客户端向缓存页面发出请求。

curl http://abcdomain.com/mypage.html -s -I -H "secret-header:true"

这将返回该项的新副本,并替换缓存中的内容。


10
为什么我只能给这个点赞一次?我想点赞无数次 :) - Spock
3
仅当新的页面也可以进行缓存时,它才能更新缓存页面。如果您已经删除了一个页面(404或其他错误现在由后端提供),页面现在发送Set-Cookie或“Content-Control:private”标头,则缓存内容将不会被“作废”。 - rbu
3
这个 "add_header X-Cache-Status $upstream_cache_status;" 功能太酷了! - Maxim Masiutin
1
非常感谢。缓存失效的技巧很不错,关于nginx的教程真的很少。 - Ivan Semochkin
5
自您发布此内容以来,情况是否有所改变?我可以成功获取带有“secret-header”的新副本,但是一旦我删除头部,就会再次获得缓存版本... - Pluc
显示剩余7条评论

72

如果您没有通过proxy_cache_path配置缓存区并在其内使用(例如在位置块中),那么通过proxy_cache将不会缓存任何内容。

如果您已经配置了缓存区,那么根据nginx作者的说法,只需从缓存目录中删除所有文件即可。

最简单的方法:find /path/to/your/cache -type f -delete


在删除文件后,我的错误日志中出现了以下内容:[crit] 1640#0: unlink() "/path/to/cache/85/1cc5328db278b328f2c200c65179ad85" failed (2: No such file or directory) - Collin Anderson
1
是的,每当我部署更改时,我都会通过脚本自动清除我的网站缓存,重新加载nginx也无法解决问题。 - Collin Anderson
Nop,即使您不使用代理,Nginx也会缓存某些内容,但这是Nginx + VirtualBox的一个错误。 - Thomas Decaux
1
这听起来相当含糊。你能详细解释一下吗?它似乎与手头的话题无关。 - Gnarfoz
1
搜索nginx配置文件中的proxy_cache_path,以查找缓存路径,例如grep -r proxy_cache_path /etc/nginx/。我的设置在/etc/nginx/conf.d/proxy_cache.conf中,路径为/var/lib/nginx/proxy - here
显示剩余5条评论

25

您可以删除nginx的缓存目录,或者您可以搜索特定文件:

grep -lr 'http://mydomain.pl/css/myedited.css' /var/nginx/cache/*

删除一个文件即可刷新nginx。


1
为了精确匹配,您可以在搜索词后面添加 **$**。例如 grep -lr 'http://mydomain.pl/css/myedited.css$' /var/nginx/cache/* - Jifeng Zhang
1
不幸的是,我得到了以下输出 grep: /var/nginx/cache/*: No such file or directory 我正在使用Ubuntu 14.04.3 LTS和nginx/1.8.1。有什么想法吗? - b00r00x0
尝试以下命令在 /var/nginx/cache 目录下搜索文件:sudo find /var/nginx/cache -type f -exec grep -l '/css/myedited.css' {} \; - jaybrau
1
我相信它是 /var/cache/nginx/*(路径中在nginx之前的cache目录)。 - Randy Lam

20

我运行一个非常简单的Bash脚本,只需要10秒钟就能完成工作,并在完成后发送一封邮件给我。

#!/bin/bash
sudo service nginx stop
sudo rm -rf /var/cache/nginx/*
sudo service nginx start | mail -s "Nginx Purged" me@gmail.com
exit 0

17

我也遇到了这个问题。

  • 找不到任何nginx/cache文件夹
  • sendfile被关闭了

我的域名使用了cloudflare.com的DNS(非常好的服务!)。啊哈!它就在那里:

cloudflare.com -> 缓存 -> 清空缓存(我清空了所有的缓存)这解决了我的问题!


3
这会清除Cloudflare的边缘缓存,但不会清除您自己服务器上的Nginx缓存。 - mahemoff
1
作为建议,我认为这是一个有效的答案。 - Fernando Kosh
2
这是非常好的答案。我花了几个小时来查找为什么一些文件仍然被缓存,但却猜不到是 CloudFlare 的问题。谢谢! - undefinedman

15

这个问题有两个答案。

  • 一个是使用nginx作为反向缓存
  • 另一个是通过输入头信息来清除浏览器缓存(即本答案)

使用方法:

expires modified +90d;

E.G.:

location ~* ^.+\.(css|js|jpg|gif|png|txt|ico|swf|xml)$ {
    access_log off;
    root /path/to/htdocs;
    expires modified +90d;
}

我尝试了这个实现,因为我遇到了类似的问题。然而,在我进行更改后,它显示了默认的Nginx页面。我正在使用Niginx作为负载均衡器和代理,也许需要更改根目录吗? - Aaron

11

我觉得这很有用

grep -lr 'jquery.js' /path/to/nginx/cache/folder/* | xargs rm

搜索,如果找到则删除。


11

在我的nginx安装中,我发现我必须进入:

sudo rm -rf /opt/nginx/cache

如果你知道你的nginx安装路径,并能找到缓存目录,那么也可以这样做。在执行rm -rf命令时要非常小心,如果在错误的目录中,可能会删除整个硬盘。


3
在此之后,您需要重新启动NGINX。 - Eliel Haouzi
1
那就是不好的部分。 - kidz

11

我们有一个非常大的nginx缓存(几个GB),偶尔需要清除。我已经编写了一个脚本,可以即时清除缓存(就Nginx而言),然后删除缓存目录,而不会使主应用程序饥饿并进行磁盘I/O。

总之:

  1. 将缓存文件夹移动到新位置(在同一文件系统上!)(这不会中断任何打开的文件描述符)
  2. 重新创建原始的空缓存文件夹
  3. 重新加载Nginx(优雅的重载,其中Nginx让旧工作进程完成正在处理的请求)
  4. 删除旧缓存数据

这是针对Ubuntu 16.04 LTS的脚本,缓存位于/mnt/nginx-cache

#!/bin/bash
set -e

TMPCACHE=`mktemp --directory --tmpdir=/mnt nginx-cache-XXXXXXXXXX`
TMPTEMP=`mktemp --directory --tmpdir=/mnt nginx-temp-XXXXXXXXXX`

# Move the old cache folders out of the way
mv /mnt/nginx-cache $TMPCACHE
mkdir -p /mnt/nginx-cache
chmod -R 775 /mnt/nginx-cache
chown www-data:www-data /mnt/nginx-cache

mv /mnt/nginx-temp $TMPTEMP
mkdir -p /mnt/nginx-temp
chmod -R 775 /mnt/nginx-temp
chown www-data:www-data /mnt/nginx-temp

# Tell Nginx about the new folders.
service nginx reload

# Create an empty folder.
rm -rf /mnt/empty
mkdir -p /mnt/empty

# Remove the old cache and old temp folders w/o thrashing the disk...
# See http://serverfault.com/questions/546177/how-to-keep-subtree-removal-rm-rf-from-starving-other-processes-for-disk-i
# Note: the `ionice` and `nice` may not actually do much, but why not?
ionice -c 3 nice -19 rsync -a --delete /mnt/empty/ $TMPCACHE
ionice -c 3 nice -19 rsync -a --delete /mnt/empty/ $TMPTEMP
rm -rf $TMPCACHE
rm -rf $TMPTEMP

rm -rf /mnt/empty

如果有帮助的话,这是我们使用的Nginx配置:

upstream myapp {
    server localhost:1337 fail_timeout=0;
}

proxy_cache_path /mnt/nginx-cache/app levels=2:2:2 keys_zone=app_cache:100m inactive=1y max_size=10g;
proxy_temp_path  /mnt/nginx-temp/app;

server {
    listen   4316 default;
    server_name  myapp.com;

    location / {
        proxy_pass http://appserv;
        proxy_cache app_cache;
        proxy_cache_valid 200 1y;
        proxy_cache_valid 404 1m;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接