Wyłącz buforowanie podczas udostępniania plików statycznych za pomocą Nginx (dla programistów)

89

Używamy Nginx do obsługi plików statycznych na platformie programistycznej. Ponieważ jest to platforma programistyczna, chcielibyśmy wyłączyć buforowanie, aby każda zmiana była propagowana na serwer. Konfiguracja VHost jest dość prosta:

server {
  server_name  static.server.local;
  root /var/www/static;

  ## Default location
  location / {
    access_log        off;
    expires           0;
    add_header        Cache-Control private;
  } 
}

Gdy uzyskujemy dostęp do pliku HTML ( http: //static.server.local/test.html ), nie mamy problemu: serwer zwraca kod 304 Niezmodyfikowany , dopóki plik nie zostanie zmieniony, i odpowiedź 200 OK z zmodyfikowany plik po zmianie pliku.
Wydaje się jednak, że zachowuje się inaczej w przypadku pliku JavaScript lub CSS. Po zmianie pliku otrzymujemy odpowiedź 200 OK zgodnie z oczekiwaniami, ale ze starym tekstem.
Czy w Nginx jest wewnętrzny mechanizm pamięci podręcznej, który mógłby wyjaśnić to zachowanie? Lub jakąś konfigurację, którą powinniśmy dodać?

Na marginesie, oto nagłówek zwracany przez Nginx, gdy plik został zmodyfikowany (wydaje się poprawny):

Accept-Ranges:bytes
Cache-Control:max-age=0
private
Connection:keep-alive
Content-Length:309
Content-Type:text/css
Date:Fri, 13 May 2011 14:13:13 GMT
Expires:Fri, 13 May 2011 14:13:13 GMT
Last-Modified:Fri, 13 May 2011 14:13:05 GMT
Server:nginx/0.8.54

Edytuj
Po wypróbowaniu różnych ustawień expiresdyrektywy i Cache-Controlnagłówka przeprowadziłem dalsze dochodzenia. W rzeczywistości serwer jest zainstalowany na systemie Ubuntu gościa VirtualBox, a dane są odczytywane z folderu współdzielonego na hoście Mac OSX.
Jeśli plik jest edytowany z IDE (NetBeans) na hoście, wydaje się, że zmiany nie pojawiają się, natomiast jeśli edytuję go bezpośrednio na gościu (używając VIM), jest on odświeżany.
Dziwne jest to, że nie zachowuje się podobnie z plikami HTML.
Całkiem zagadkowe.

Edycja 2 (ODPOWIEDŹ)
Rzeczywiście, źródło problemu było bardziej po stronie VirtualBox. A raczej konflikt między VirtualBox a opcją „sendfile” serwera.
Ten link VirtualBox Hates Sendfile dał mi rozwiązanie: wyłącz flagę sendfile w konfiguracji serwera na off :

sendfile  off;

Mam nadzieję, że może to również pomóc innej osobie używającej VirtualBox do programowania. :)
Istnieje kilka dodatkowych informacji na forum VirtualBox .

Olivier Chappe
źródło
3
Czy używasz nginx w vagrant vm i używasz wspólnego fs? Było kilka raportów o twoich objawach używania tej kombinacji w #nginx.
kolbyjack
3
Mógłbym cię dosłownie przytulić !! Spędziłem 48 godzin przeklinając i kompletnie oszalałem z tego dokładnego problemu ..., skompilowałem kilka razy nginx, poświęciłem kilka małych puszystych stworzeń różnym bóstwom, nauczyłem się instrukcji buforowania od tyłu ... wszystko po to, aby dowiedzieć się, że naprawienie tego jest dziwne dzięki temu, że VirtualBox jest dziwny!
James Butler,
13
Byłoby o wiele jaśniej, gdybyś opublikował swoją odpowiedź jako odpowiedź i zaakceptował ją, aby każdy mógł zobaczyć, że problem został rozwiązany.
Zombaya
Tego ranka trafił mnie ten błąd. Bez tego nie zdałbym sobie sprawy, że to tylko folder udostępniony. Dzięki!
JaffaTheCake,
Dzięki! Rozumiem, że na razie nie ma innego sposobu na naprawienie tego błędu? Co zrobić, jeśli chcę włączyć
plik wysyłania

Odpowiedzi:

57

Ponieważ odpowiedź jest w jakiś sposób ukryta w pytaniu - oto rozwiązanie dla nginx w środowisku VirtualBox jako samodzielna odpowiedź.

W konfiguracji nginx (zwykle /etc/nginx/nginx.conf) lub pliku konfiguracyjnym vhost zmień sendfileparametr na off:

sendfile  off;

Choć sendfileleży u podstaw sławy Nginx (niesamowicie szybka statyczna obsługa niskiego poziomu plików statycznych), może to być zmorą dla rozwoju lokalnego, np. JavaScript, który często się zmienia i trzeba go ponownie załadować. Niemniej jednak plik wysyłania Nginx jest inteligentny i prawdopodobnie nie jest to problem większości ludzi; sprawdź także opcje „wyłącz pamięć podręczną” w przeglądarce!

lorem małpa
źródło
5
+1, chociaż odpowiedź powinna wyjaśniać, dlaczego jest to konieczne, zamiast skutecznie pozostawiać czytelnikom, aby znaleźli / ponownie przeczytali pytanie w poszukiwaniu referencji. Postaw odpowiedź samodzielnie -> lepiej.
AD7six
2
To wydaje mi się odpowiedzią. Problem wydaje się występować w przypadku konkretnej kombinacji Sendfile, VirtualBox i hosta OSX. abitwiser.wordpress.com/2011/02/24/virtualbox-hates-sendfile forums.virtualbox.org/viewtopic.php?f=1&t=24905
Steve Bennett
sendfilejest w porządku nawet dla lokalnego środowiska programistycznego; to tylko VirtualBox, w którym jest zepsuty. Z tego powodu (wielu z nich) zalecam unikanie VirtualBox ...
Michael Hampton
dzięki za zapisanie, dziwny problem z Vagrant / VirtualBox / Ubuntu / Wordpress, domyślam się, że moje środowisko PROD jest bezpieczne z domyślnie włączonym plikiem sendfile.
sonjz
Rozwiązuje mój problem z nginx i dokerem
PascalTurbo,
15

ustaw tag wygasania na

expires off;

i nie powinien w ogóle ustawiać nagłówków wygasających, może to również niepoprawnie buforować pliki przeglądarki

anthonysomerset
źródło
Niestety próbowałem tego również, expires -1a zachowanie jest nadal takie samo.
Olivier Chappe
Jeśli chodzi o przeglądarkę, pomyślałem o tych możliwościach: najpierw próbowałem w Chrome, a po zmodyfikowaniu pliku otworzyłem go po raz pierwszy w przeglądarce Firefox: wciąż mam pierwszą wersję pliku.
Olivier Chappe
również nagłówek kontroli pamięci podręcznej powinien być prawdopodobnie CACHE-CONTROL: NO-CACHE
anthonysomerset
lub całkowicie usuń nagłówek kontroli pamięci podręcznej - przepraszam, nie mogłem edytować poprzedniego komentarza
anthonysomerset
1
W systemie Windows „wygasa” nadal nie wyłącza buforowania plików HTML. Bardzo frustrujące, gdy aktualizuję plik w moim IDE, ale! $ #% Ing nginx obsługuje starą wersję.
Dan Dascalescu
2

Jest to stary błąd w VirtualBox (patrz: # 819 , # 9069 , # 12597 , # 14920 ), w którym vboxvfs wydaje się mieć problemy z dostępem mmapa do synchronizowanych plików.

Może się to zdarzyć, gdy edytujesz plik poza maszyną wirtualną i spodziewasz się tej samej zmiany w maszynie wirtualnej.

Aby obejść ten problem, należy wyłączyć obsługę wysyłania plików jądra w celu dostarczania plików do klienta poprzez wyłączenie EnableSendfileopcji . Jest to szczególnie kłopotliwe dla plików montowanych przez NFS lub SMB.

DoNginx (zmiana nginx.conf), np

sendfile off;

Podobne dla Apache (w httpd.conflub w pliku vhosts), np

<Directory "/path-to-nfs-files">
  EnableSendfile Off
</Directory>

Po zmianie załaduj ponownie Apache.


Innym potencjalnym rozwiązaniem jest po prostu pamiętaj, aby nie edytować plików na hoście lub próbować ponownie edytować ten sam plik, ale na maszynie wirtualnej.


Innym obejściem jest upuszczenie pamięci podręcznej systemu Linux, np

echo 1 > /proc/sys/vm/drop_caches

Lub, aby wyczyścić pamięć podręczną co sekundę (jak w tym poście ), spróbuj:

watch -n 1 $(sync; echo 1 > /proc/sys/vm/drop_caches)

Uwaga: Numer 1 oznacza zwolnienie pamięci podręcznej, 2 dla dentries i i-węzłów, 3 dla pagecache, dentries i i-węzłów.


Powyższy problem może być powielana według następującego programu mmap testu, zob mmap-problem.c.

kenorb
źródło
1

Jest późno, ale wciąż jest zaznaczony bez odpowiedzi, więc wezmę dźgnięcie. Tylko na chichoty, czy próbowałeś:

location ~* \.(css|js)$ {
    expires 0;
    break;
}

Sam tego nie próbowałem, ale od czasu do czasu nauczyłem się próbować tego rodzaju z Nginx w kontenerze serwera, gdy mam problemy podobne do tego ...

ColtonCat
źródło