Як очистити кеш-пам'ять nginx?


250

Я використовую nginx як передній сервер, я змінив файли CSS, але nginx все ще обслуговує старі.

Я спробував перезапустити nginx, не маючи успіху, і я гугл, але не знайшов дійсного способу його очищення.

У деяких статтях говориться, що ми можемо просто видалити кеш-каталог:, var/cache/nginxале такого каталогу на моєму сервері немає.

Що мені робити зараз?


1
Детальніше про вашу конфігурацію Nginx буде дуже корисною. Ви використовуєте proxy_cache?
Олександр Азаров

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

5
Nginx за замовчуванням не кешується.
Олександр Азаров

30
Ви працюєте в virtualbox / vargant vm? Якщо так, спробуйте вимкнути sendfile, оскільки вони не грають добре разом.
колб'як

5
Ви впевнені, що кешування знаходиться на стороні nginx? Ви перевірили поведінку за допомогою такого інструменту, як curl? Часто такою проблемою є просто кешування на стороні клієнта, а не запит оновленого ресурсу, оскільки сказано, що старий ресурс буде дійсним протягом тривалого часу до закінчення максимуму; чи щось подібне.
колб'як

Відповіді:


185

У мене була точно така ж проблема - я запускав свій nginx у Virtualbox. У мене не було ввімкнено кешування. Але схоже , sendfileбув встановлений onв nginx.confі що викликає проблеми. @kolbyjack згадував це вище у коментарях.

Коли я вимкнувся sendfile- спрацювало чудово.

Це відбувається тому:

Sendfile використовується для "копіювання даних між одним дескриптором файлу та іншим" і, мабуть, має певні проблеми при запуску у середовищі віртуальної машини або принаймні під час запуску через Virtualbox. Якщо вимкнути цю конфігурацію в nginx, статичний файл подається за допомогою іншого методу, і ваші зміни будуть відображені негайно та без сумнівів

Це пов’язано з цією помилкою: https://www.virtualbox.org/ticket/12597


7
Перейдіть за цим посиланням
Sian Lerk Lau

У моєму випадку альтернативне вирішення - увімкнути gzip для цих типів файлів. У будь-якому випадку проблема буде вирішена.
Дінгл

Дякую вам та кольбіяку так сильно за відповідь. Врятувало мені життя.
T1000

1
Я використав наступний 'sudo vim /etc/nginx/nginx.conf' і змінив 'sendfile on' на 'sendfile off'
Koray Güclü

12
Я вимкнув sendfile. Нещастить.
Марукоботто

110

Ви також можете обходити / повторно кешувати у файлі за допомогою файлу, використовуючи

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", кешований вміст не буде "недійсним".
rbu

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)
Collin Anderson

Неодноразово чи лише один раз? Це не повинно бути актуальною проблемою. Це, мабуть, просто означає, що менеджер кеша намагався видалити файл, який ви вже видалили. Можливо, перезавантаження nginx (nginx -s reload) може допомогти, якщо ви отримуєте повідомлення кілька разів. (Не впевнений, чи це повторно реалізує кеш-менеджер.)
Gnarfoz

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

Nop Nginx кешує щось, навіть якщо ви не використовуєте проксі-файли, але це помилка з Nginx + VirtualBox.
Томас Деко

1
Це звучить досить невиразно. Не могли б ви детальніше зупинитися на цьому? Здається, це не пов’язано з цією темою.
Гнарфос

20

Ви можете видалити кеш-каталог з nginx або Ви можете шукати конкретний файл:

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

І видаліть лише один файл, щоб оновити їх nginx.


1
Щоб отримати точно звернення, ви можете додати $ до пошукової фрази. Likegrep -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

Спробуйте sudo find /var/nginx/cache -type f -exec grep -l '/css/myedited.css' {} \;
скопіювати

Я вважаю, що це / var / cache / nginx / * (кер dir перед nginx у шляху)
Randy Lam

15

У цьому питанні є дві відповіді.

  • Один для nginx як зворотного кешу
  • Інший для очищення кеш-пам’ятника браузера шляхом введення заголовка (цей)

Використання:

expires modified +90d;

EG:

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 / кеш
  • 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 може доставити вам шкоди, якщо ваша програма не поверне кеш-відповідь на цей конкретний запит, коли ви запускаєте його.

Якщо, наприклад, ваш додаток надсилає файл cookie з кожним першим запитом, то сценарій, який запускає 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 до 1s (я не впевнений, чи це по суті те саме, що повністю відключити кеш файлів).


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;

    ....
}
...
}

Зверху динамічно створюється папка під назвою "nginx_cache" в / tmp / для зберігання кешованого вмісту.


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 - це лише те, що спрацювало)

Рішення: У VM знайти спільний файл (файл css в моєму випадку). Відкрийте нано і порівняйте з файлом у вікні спільного доступу (вони здаються однаковими). У VM збережіть спільний файл з nano. Усі зміни тепер відображаються в браузері. Не знаю, чому це працює, але це було в моєму випадку.

ОНОВЛЕННЯ: Після перезавантаження сервера VM проблема повернулася. Дотримуючись вказівок у розділі Solution, 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.