Как очистить кеш nginx?


251

Я использую nginx в качестве фронтального сервера, я изменил файлы CSS, но nginx все еще обслуживает старые.

Я попытался перезапустить nginx, но безуспешно, и у меня есть Google, но я не нашел правильного способа его очистки.

В некоторых статьях говорится, что мы можем просто удалить каталог кэша:, var/cache/nginxно на моем сервере такого каталога нет.

Что мне теперь делать?


1
Более подробная информация о вашей конфигурации Nginx будет очень полезна. Вы используете proxy_cache?
Александр Азаров

Нет, я просто использовал конфигурацию по умолчанию и искал строку cache, но не нашел ее в файлах конфигурации
Freewind

5
Nginx не кешируется по умолчанию.
Александр Азаров

30
Вы работаете в виртуальной коробке / VARGANT VM? Если это так, попробуйте отключить sendfile, так как они не очень хорошо играют вместе.
kolbyjack

5
Вы уверены, что кэширование на стороне nginx, тогда? Вы проверили поведение с помощью такого инструмента, как curl? Часто проблема, такая как это просто кэширование на стороне клиента, не запрашивающее обновленный ресурс, потому что было сказано, что старый ресурс будет действителен долгое время, expires max; или что-то подобное.
kolbyjack

Ответы:


185

У меня была точно такая же проблема - я запускал свой nginx в Virtualbox. У меня не было включено кэширование. Но похоже, что sendfileбыло установлено onвnginx.conf и это вызывало проблему. @kolbyjack упомянул это выше в комментариях.

Когда я выключил sendfile- все работало нормально.

Это потому что:

Sendfile используется для «копирования данных между одним файловым дескриптором и другим» и, по-видимому, имеет некоторые реальные проблемы при запуске в среде виртуальной машины или, по крайней мере, при запуске через Virtualbox. Отключение этой конфигурации в nginx приводит к тому, что статический файл обслуживается другим способом, и ваши изменения будут отражены немедленно и без вопросов.

Это связано с этой ошибкой: https://www.virtualbox.org/ticket/12597



В моем случае альтернативный обходной путь - включить gzip для этих типов файлов. В любом случае проблема решена.
Дингл

Огромное спасибо КолбиДжеку за ответ. Спас мою жизнь.
T1000

1
Я использовал следующий «sudo vim /etc/nginx/nginx.conf» и изменил «sendfile on» на «sendfile off»
Koray Güclü

12
Я выключил sendfile. Не повезло.
Марукоботто

111

Вы также можете обойти / повторно кэшировать файл за файлом, используя

proxy_cache_bypass $http_secret_header;

и в качестве бонуса вы можете вернуть этот заголовок, чтобы увидеть, получили ли вы его из кэша (вернет «HIT») или с сервера контента (вернет «BYPASS»).

add_header X-Cache-Status $upstream_cache_status;

чтобы истечь / обновить кэшированный файл, используйте curl или любой другой клиент для отправки запроса на кэшированную страницу.

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

это вернет свежую копию элемента, а также заменит то, что находится в кеше.


7
Почему я могу проголосовать только один раз? Я хочу сделать газиллион :)
Спок

2
Это может обновлять кэшированные страницы только тогда, когда новая страница также кэшируется. Если вы удалили страницу (теперь 404 или другие ошибки обслуживаются бэкэндом), страница теперь отправляет Set-Cookie или заголовок «Content-Control: private», кэшированное содержимое не будет «признано недействительным».
СБР

3
Это "add_header X-Cache-Status $ upstream_cache_status;" это такая классная особенность!
Максим Масютин

1
большое спасибо. хороший совет для аннулирования кэша, есть так мало уроков о nginx
Иван Семочкин

4
Изменилось ли это с тех пор, как вы написали? Я могу успешно получить новую копию с «секретным заголовком», но как только я
удаляю

60

Если вы не настроили зону кэша через 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)
Коллин Андерсон

Неоднократно или только один раз? Это не должно быть актуальной проблемой. Вероятно, это просто означает, что менеджер кэша попытался удалить файл, который вы уже удалили. Может быть, перезагрузка nginx (nginx -s reload) может помочь, если вы получаете сообщение повторно. (Не уверен, что это также
приводит к повторной

1
да, я автоматически очищаю кеш для своего веб-сайта скриптом всякий раз, когда внедряю изменение, и перезагрузка nginx также не исправляет это.
Коллин Андерсон

Nop Nginx что-то кеширует, даже если вы не используете прокси, но это ошибка в Nginx + VirtualBox.
Томас Деко

1
Это звучит довольно расплывчато. Не могли бы вы уточнить это? Не похоже, что это связано с обсуждаемой здесь темой.
Gnarfoz

20

Вы можете удалить каталог кеша 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/*
Цзифэн Чжан

1
К сожалению, я получил следующий вывод: grep: /var/nginx/cache/*: No such file or directoryя использую Ubuntu 14.04.3 LTS и nginx / 1.8.1. Любая идея?
b00r00x0

Попробуйте выполнить следующее для grep файлов в / var / nginx / cache:sudo find /var/nginx/cache -type f -exec grep -l '/css/myedited.css' {} \;
jaybrau

Я считаю, что это / var / cache / nginx / * (директория кеша перед nginx в пути)
Рэнди Лам

15

В этом вопросе два ответа.

  • Один для nginx как обратный кеш
  • Другой для очистки кэша браузера путем ввода заголовка (этот)

Использование:

expires modified +90d;

НАПРИМЕР:

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

Я попробовал эту реализацию, потому что у меня похожая проблема. Тем не менее, после того, как я внес изменение - он показывает страницу Nginx по умолчанию. Я использую Niginx в качестве LB с прокси, мне нужно сменить root?
Аарон

10

Я нашел это полезным

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

Ищите, и если нашли, то удалите.


9

В моей установке nginx я обнаружил, что должен был перейти к:

/opt/nginx/cache

и

sudo rm -rf *

в этом каталоге. Если вы знаете путь к вашей установке nginx и можете найти каталог кеша, то это может сработать для вас. Будьте очень осторожны с rm -rfкомандой, если вы находитесь не в том каталоге, вы можете удалить весь жесткий диск.


2
после этого нужно перезапустить NGINX
Элиэль Хаузи

И это плохая часть
Kidz

9

Я запускаю очень простой скрипт 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

8

У меня тоже была эта проблема.

  • Не удалось найти ни одной папки nginx / cache
  • sendfile был выключен

Мой домен использует cloudflare.com для DNS (отличный сервис!). Ага! Там это было:

cloudflare.com -> кеширование -> Очистить кэш (я все очистил) Это решило мою проблему!


2
Это очищает края кэша Cloudflare. Он не очищает кэш Nginx на вашем собственном сервере.
mahemoff

В качестве совета, я думаю, это правильный ответ.
Фернандо Кош

Это был отличный ответ. Я копал часы, почему некоторые файлы все еще кэшируются, и не мог догадаться, что это «ошибка» CloudFlare. Спасибо!
undefinedman

6

У нас есть очень большой кэш nginx (гигабайт), который нам иногда нужно стереть. Я разработал скрипт, который мгновенно очищает кеш (что касается Nginx), а затем удаляет каталог кеша, не останавливая основное приложение для дискового ввода-вывода.

В итоге:

  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;
    }
}

5

Для тех, у кого другие решения не работают, проверьте, используете ли вы службу DNS, такую ​​как CloudFlare . В этом случае активируйте «Режим разработки» или воспользуйтесь инструментом «Очистить кэш».


5

Обратите внимание, что proxy_cache_bypass может навредить вам, если ваше приложение не вернет кэшируемый ответ на тот конкретный запрос, когда вы его инициируете.

Если, например, ваше приложение отправляет куки-файл при каждом первом запросе, то скрипт, который запускает proxy_pass_bypass через curl, вероятно, получит этот куки-файл в ответе, и nginx не будет использовать этот ответ для обновления кэшированного элемента.


3
find /etc/nginx/cache_folder -type d -exec rm -rvf {} \;
mkdir /etc/nginx/cache_folder
service nginx restart

Будьте осторожны, чтобы правильно указать правильный путь.


3

Для тех, кто пытался удалить файлы кеша nginx, и он либо не работал, либо работал с перебоями, взгляните на ваши настройки open_file_cache. Если этот параметр включен и настроен для кэширования дескриптора файла в течение длительного времени, то Nginx может по-прежнему видеть версию кэшированного файла, даже после того, как вы удалили его с диска. Мне пришлось уменьшить open_file_cache_valid до 1 с (я не уверен, что это по сути то же самое, что полное отключение файлового кэша).


2

На моем сервере папка кеша nginx находится по адресу /data/nginx/cache/

Поэтому я удалил это только: sudo rm -rf /data/nginx/cache/

Надеюсь, это кому-нибудь поможет.


2

Если вы хотите очистить кеш определенных файлов, вы можете использовать proxy_cache_bypassдирективу. Вот как ты это делаешь

location / {
    proxy_cache_bypass $cookie_nocache $arg_nocache;
    # ...
}

Теперь, если вы хотите обойти кеш, вы получите доступ к файлу, передав параметр nocache

http://www.example.com/app.css?nocache=true


1
Я думаю, что это может быть использовано для атаки и использования полосы пропускания на вашем сайте.
Марсело Агимовель

1
Разве это не обходит кеш для текущего запроса ( app.css?nocache=true), а исходный файл (без запроса) остается в кэше ( app.css)?
adrianTNT

1

Вы можете добавить конфигурацию в nginx.conf следующим образом.

...
http {
proxy_cache_path  /tmp/nginx_cache levels=1:2 keys_zone=my-test-cache:8m max_size=5000m inactive=300m;

server {
    proxy_set_header X- Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_cache my-test-cache;
    proxy_cache_valid  200 302  1m;
    proxy_cache_valid  404      60m;
    proxy_cache_use_stale   error timeout invalid_header updating;
    proxy_redirect off;

    ....
}
...
}

Сверху в / tmp / динамически создается папка с именем «nginx_cache» для хранения кэшированного содержимого.


1

Есть один правильный способ удалить только кеш-файлы, который соответствует любому KEY. Например:

grep -lr 'KEY: yahoo' /var/lib/nginx/cache | xargs rm -rf

Это удаляет все кеш-файлы, которые соответствуют KEY "yahoo / *", если в nginx.conf было установлено:

proxy_cache_key $host$uri;

1

Мы используем nginx для кэширования большого количества вещей. В каталоге кеша находятся десятки тысяч элементов. Чтобы найти элементы и удалить их, мы разработали несколько скриптов, чтобы упростить этот процесс. Вы можете найти репозиторий для этих скриптов ниже:

https://github.com/zafergurel/nginx-cache-cleaner

Идея проста. Создать индекс кэша (с ключами кэша и соответствующими файлами кэша) и выполнить поиск в этом файле индекса. Это действительно помогло нам ускорить поиск элементов (с минут до секунды) и соответственно удалить их.


1

В моем случае, touchэтот файл Css делает его похожим на измененные ресурсы (фактически touchничего не делает с файлом, кроме изменения времени последнего изменения), поэтому браузер и nginx будут применять последние ресурсы


0

Я столкнулся с подобной проблемой:

Настройка системы и проблема: (В виртуальной коробке я использую ubuntu и nginx для веб-хостинга - обновления веб-страниц PHP не отражают изменения во внешнем CSS-файле). Я занимаюсь разработкой веб-сайта на машине с Windows и передаю файлы в nginx через общую папку. Кажется, что nginx не воспринимает изменения в css-файле (обновление каким-либо образом не помогает. Изменение имени css-файла - единственное, что сработало)

Решение: На ВМ найдите общий файл (в моем случае файл css). Откройте с помощью nano и сравните с файлом в Windows Share (они выглядят одинаково). На ВМ сохраните общий файл с помощью nano. Все изменения теперь отражены в браузере. Не уверен, почему это работает, но в моем случае.

ОБНОВЛЕНИЕ: после перезагрузки сервера VM проблема вернулась. Следуя инструкциям в разделе Решение, CSS снова стал реагировать на обновления.


-1

В моем случае это был включенный opcache в /etc/php/7.2/fpm/php.ini (Ubuntu):

opcache.enable=1

Если установить значение 0, сервер загрузит последнюю версию файлов (php).

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.