Vô hiệu hóa bộ đệm ẩn khi phục vụ các tệp tĩnh với Nginx (để phát triển)


89

Chúng tôi đang sử dụng Nginx để phục vụ các tệp tĩnh trên nền tảng phát triển. Vì nó là một nền tảng phát triển, chúng tôi muốn tắt bộ nhớ đệm để mỗi thay đổi được truyền đến máy chủ. Cấu hình của Vhost khá đơn giản:

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

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

Khi chúng tôi truy cập tệp HTML ( http: //static.server.local/test.html ), chúng tôi không gặp vấn đề gì: máy chủ trả về mã 304 Không được sửa đổi miễn là tệp không bị thay đổi và phản hồi 200 OK với các tập tin sửa đổi khi tập tin được thay đổi.
Tuy nhiên, nó dường như hoạt động khác với tệp Javascript hoặc tệp CSS. Khi tệp được thay đổi, chúng tôi nhận được phản hồi 200 OK như mong đợi, nhưng với văn bản cũ.
Có một cơ chế bộ nhớ cache nội bộ trong Nginx có thể giải thích hành vi này? Hoặc một số cấu hình mà chúng ta nên thêm?

Lưu ý phụ, đây là tiêu đề được Nginx trả về khi tệp đã được sửa đổi (có vẻ đúng):

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

Chỉnh sửa
Sau khi thử các cài đặt khác nhau với expireschỉ thị và Cache-Controltiêu đề, tôi đã thực hiện một số điều tra thêm. Trên thực tế, máy chủ được cài đặt trên Ubuntu khách VirtualBox và dữ liệu được đọc từ thư mục dùng chung trên máy chủ Mac OSX.
Nếu tệp được chỉnh sửa từ IDE (NetBeans) trên máy chủ, có vẻ như các thay đổi không xuất hiện trong khi tôi chỉnh sửa trực tiếp trên máy khách (sử dụng VIM), thì nó được làm mới.
Điều kỳ lạ là nó không hoạt động tương tự với các tệp HTML.
Khá khó hiểu.

Chỉnh sửa 2 (TRẢ LỜI)
Thật vậy, nguồn gốc của vấn đề nằm ở phía VirtualBox. Hay đúng hơn là xung đột giữa VirtualBox và tùy chọn "sendfile" của máy chủ.
Liên kết này VirtualBox Ghét Sendfile đã cho tôi giải pháp: chuyển cờ sendfile trong cấu hình máy chủ sang tắt :

sendfile  off;

Hy vọng điều này cũng có thể giúp người khác sử dụng VirtualBox để phát triển. :)
Có một số thông tin bổ sung trên diễn đàn VirtualBox .


3
Bạn đang chạy nginx trong một vm mơ hồ và sử dụng fs được chia sẻ? Đã có một số báo cáo về các triệu chứng của bạn bằng cách sử dụng kết hợp đó trong #nginx.
kolbyjack

3
Tôi thực sự có thể ôm bạn !! Đã dành 48 giờ để nguyền rủa và phát điên hoàn toàn với vấn đề chính xác này .., đã biên dịch lại nginx một vài lần, hy sinh một số sinh vật lông xù nhỏ cho các vị thần, học các chỉ thị bộ đệm ngược ... tất cả để tìm ra một điều kỳ quặc để khắc phục cảm ơn VirtualBox thật kỳ lạ!
James Butler

13
Sẽ rõ ràng hơn rất nhiều nếu bạn đăng câu trả lời của mình dưới dạng câu trả lời và chấp nhận nó để mọi người có thể thấy rằng vấn đề này đã được giải quyết.
Zombaya

Tôi đã gặp phải lỗi này sáng nay. Sẽ không nhận ra nó đã xuống thư mục chia sẻ mà không có điều này. Cảm ơn!
JaffaTheCake

Cám ơn! Theo tôi hiểu bây giờ không còn cách nào khác để sửa lỗi này? Nếu tôi cần sendfile thì sao? :-)
Dmitry Belaventsev

Câu trả lời:


57

Vì câu trả lời bị ẩn đi trong câu hỏi - đây là giải pháp cho nginx trong môi trường VirtualBox dưới dạng câu trả lời độc lập.

Trong cấu hình nginx của bạn (usally /etc/nginx/nginx.conf) hoặc tệp cấu hình vhost thay đổi sendfiletham số thành off:

sendfile  off;

Mặc dù sendfilelà trung tâm của sự nổi tiếng của Nginx (hiệu quả phục vụ tệp tĩnh cấp thấp cực nhanh), nó có thể là một nguyên nhân cho sự phát triển cục bộ, ví dụ Javascripts thay đổi thường xuyên và cần được tải lại. Tuy nhiên, Nginx sendfile rất thông minh và có lẽ không phải là vấn đề của hầu hết mọi người; kiểm tra tùy chọn "vô hiệu hóa bộ nhớ cache" của trình duyệt của bạn là tốt!


5
+1 mặc dù câu trả lời sẽ giải thích tại sao điều đó lại cần thiết thay vì để người đọc tìm / đọc lại câu hỏi tìm kiếm tài liệu tham khảo một cách hiệu quả. Làm cho câu trả lời đứng trên chính nó -> tốt hơn.
AD7six

2
Đây dường như là câu trả lời cho tôi. Vấn đề dường như xảy ra với sự kết hợp cụ thể của Sendfile, VirtualBox và máy chủ OSX. abitwiser.wordpress.com/2011/02/24/virtualbox-hates-sendfile forum.virtualbox.org/viewtopic.php?f=1&t=24905
Steve Bennett

sendfilelà tốt cho ngay cả một môi trường phát triển địa phương; chỉ có VirtualBox mà nó bị hỏng. Đó là một lý do (trong số nhiều) Tôi khuyên bạn nên tránh VirtualBox ...
Michael Hampton

cảm ơn vì sự tiết kiệm, vấn đề lạ với Vagrant / VirtualBox / Ubuntu / Wordpress, tôi đoán môi trường SẢN XUẤT của tôi an toàn với sendfile như mặc định.
sonjz

Giải quyết vấn đề của tôi với nginx và
docker

15

đặt thẻ hết hạn của bạn thành

expires off;

và nó không nên đặt bất kỳ tiêu đề hết hạn nào cả, nó cũng có thể là các tệp bộ nhớ đệm trình duyệt của bạn không chính xác


Thật không may, tôi đã thử điều này cũng như expires -1và hành vi vẫn như vậy.
Olivier Chappe

Liên quan đến trình duyệt, tôi đã nghĩ đến khả năng này: Lần đầu tiên tôi thử dùng Chrome và sau khi sửa đổi một tệp đã mở lần đầu tiên trong Firefox: Tôi vẫn có phiên bản đầu tiên của tệp.
Olivier Chappe

Ngoài ra, tiêu đề kiểm soát bộ đệm có lẽ phải là CACHE-KIỂM SOÁT: NO-CACHE
anthonysomerset

hoặc xóa tiêu đề kiểm soát bộ đệm hoàn toàn - xin lỗi không thể chỉnh sửa nhận xét trước đó
anthonysomerset

1
Trên Windows, "hết hạn" vẫn không tắt bộ đệm ẩn của các tệp html. Rất bực bội khi tôi cập nhật một tệp trong IDE của mình, nhưng! $ #% Ing nginx phục vụ một phiên bản cũ.
Dan Dascalescu


2

Đây là lỗi cũ trong VirtualBox (xem: # 819 , # 9069 , # 12597 , # 14920 ) trong đó vboxvfs dường như có một số vấn đề với quyền truy cập vào các tệp được đồng bộ hóa.

Điều này có thể xảy ra khi bạn chỉnh sửa tệp bên ngoài VM và bạn sẽ thấy sự thay đổi tương tự trong VM.

Để khắc phục sự cố này, bạn cần phải tắt hỗ trợ sendfile kernel để gửi tệp đến máy khách bằng cách tắt EnableSendfiletùy chọn . Điều này đặc biệt rắc rối đối với các tệp được gắn NFS hoặc SMB.

Đối vớiNginx (thay đổi nginx.conf), vd

sendfile off;

Tương tự cho Apache (trong httpd.confhoặc trong tệp vhosts), vd

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

Sau khi thay đổi tải lại Apache.


Giải pháp tiềm năng khác chỉ cần nhớ là không chỉnh sửa các tệp trên máy chủ hoặc cố gắng chỉnh sửa lại cùng một tệp, nhưng trong VM.


Một cách giải quyết khác bao gồm loại bỏ Linux pagecache, vd

echo 1 > /proc/sys/vm/drop_caches

Hoặc để xóa bộ nhớ cache mỗi giây (theo bài đăng này ), hãy thử:

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

Lưu ý: Số 1 là viết tắt của miễn phí pagecache, 2 cho nha khoa và inodes, 3 cho pagecache, nha khoa và inodes.


Vấn đề trên có thể được nhân rộng bằng chương trình kiểm tra mmap sau, xem : mmap-problem.c.


1

Điều này là muộn, nhưng vẫn được đánh dấu chưa được trả lời, vì vậy tôi sẽ đâm. Chỉ để cười khúc khích, bạn đã thử:

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

Bản thân tôi đã không thử điều này, nhưng đã học cách thử loại điều này với Nginx trong một thùng chứa máy chủ theo thời gian khi tôi gặp vấn đề tương tự như thế này ...

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.