ปิดใช้งานการแคชเมื่อให้บริการไฟล์คงที่ด้วย Nginx (เพื่อการพัฒนา)


89

เรากำลังใช้ Nginx เพื่อให้บริการไฟล์คงที่บนแพลตฟอร์มการพัฒนา เนื่องจากเป็นแพลตฟอร์มการพัฒนาเราจึงต้องการปิดใช้งานการแคชเพื่อให้การเปลี่ยนแปลงแต่ละครั้งถูกส่งไปยังเซิร์ฟเวอร์ การกำหนดค่าของ VHost นั้นค่อนข้างง่าย:

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

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

เมื่อเราเข้าถึงไฟล์ HTML ( http: //static.server.local/test.html ) เราไม่มีปัญหา: เซิร์ฟเวอร์จะส่งคืนรหัส304 ไม่ถูกแก้ไขตราบใดที่ไฟล์ไม่เปลี่ยนแปลงและมีการตอบสนอง200 OKด้วย ไฟล์ที่แก้ไขเมื่อไฟล์ถูกเปลี่ยน
อย่างไรก็ตามดูเหมือนว่าจะทำงานแตกต่างจาก Javascript หรือไฟล์ CSS เมื่อไฟล์มีการเปลี่ยนแปลงเราจะได้รับการตอบสนอง200 OKตามที่คาดไว้ แต่มีข้อความเก่า
มีกลไกแคชภายในใน Nginx ที่สามารถอธิบายพฤติกรรมนี้ได้หรือไม่? หรือการกำหนดค่าบางอย่างที่เราควรเพิ่ม?

ตามหมายเหตุด้านล่างนี่คือส่วนหัวที่ส่งคืนโดย Nginx เมื่อไฟล์ถูกแก้ไข (ดูเหมือนถูกต้อง):

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

แก้ไข
หลังจากลองการตั้งค่าที่แตกต่างกับexpiresคำสั่งและCache-Controlส่วนหัวฉันทำการตรวจสอบเพิ่มเติม อันที่จริงแล้วเซิร์ฟเวอร์นั้นได้รับการติดตั้งบน VirtualBox แขก Ubuntu และข้อมูลจะถูกอ่านจากโฟลเดอร์ที่แชร์ที่อยู่บนโฮสต์ Mac OSX
หากไฟล์ถูกแก้ไขจาก IDE (NetBeans) บนโฮสต์ดูเหมือนว่าการเปลี่ยนแปลงจะไม่ปรากฏขึ้นในขณะที่ถ้าฉันแก้ไขไฟล์โดยตรงบน guest (โดยใช้ VIM) จะมีการรีเฟรช
สิ่งที่แปลกคือมันไม่ได้ทำงานเหมือนกับไฟล์ HTML
ค่อนข้างงง

แก้ไข 2 (คำตอบ) ที่
จริงต้นกำเนิดของปัญหานั้นเพิ่มเติมในด้าน VirtualBox หรือค่อนข้างขัดแย้งระหว่าง VirtualBox และตัวเลือก "sendfile" ของเซิร์ฟเวอร์
ลิงค์นี้VirtualBox เกลียด Sendfileให้ฉันแก้ปัญหา: สลับธงsendfileในการกำหนดค่าเซิร์ฟเวอร์ปิด :

sendfile  off;

หวังว่านี่จะช่วยให้บุคคลอื่นใช้ VirtualBox เพื่อการพัฒนา :)
มีบางข้อมูลเพิ่มเติมเกี่ยวกับที่มีฟอรั่ม VirtualBox


3
คุณใช้ nginx ใน vm คนจรจัดและใช้ fs ที่แชร์หรือไม่ มีรายงานหลายอาการของคุณที่ใช้ชุดค่าผสมใน #nginx
kolbyjack

3
ฉันกอดคุณได้จริงๆ !! ใช้เวลา 48 ชั่วโมงในการสาปแช่งและคลั่งไคล้กับปัญหานี้อย่างแท้จริง .. , คอมไพล์ nginx อีกสองสามครั้ง, สังเวยสิ่งมีชีวิตที่มีขนปุยเล็ก ๆ บางตัวเพื่อเทวรูปต่าง ๆ , เรียนรู้คำสั่งแคชย้อนหลัง ... ทั้งหมดเพื่อค้นหาว่า ขอบคุณ VirtualBox ที่แปลก ๆ !
James Butler

13
มันจะมีความชัดเจนมากขึ้นถ้าคุณจะโพสต์คำตอบของคุณเป็นคำตอบและยอมรับมันเพื่อให้ทุกคนเห็นว่าปัญหานี้ได้รับการแก้ไข
Zombaya

เมื่อเช้านี้ฉันได้รับผลกระทบจากข้อผิดพลาด จะไม่ได้รู้ว่ามันลงไปในโฟลเดอร์ที่ใช้ร่วมกันโดยไม่ต้องนี้ ขอบคุณ!
JaffaTheCake

ขอบคุณ! อย่างที่ฉันเข้าใจแล้วมันไม่มีวิธีอื่นในการแก้ไขข้อบกพร่องนี้ในตอนนี้? จะทำอย่างไรถ้าฉันต้องการ sendfile ให้เปิดใช้งาน :-)
Dmitry Belaventsev

คำตอบ:


57

เนื่องจากคำตอบถูกซ่อนอยู่ในคำถาม - นี่คือวิธีแก้ปัญหาสำหรับ nginx ในสภาพแวดล้อม VirtualBox เป็นคำตอบแบบสแตนด์อโลน

ในการกำหนดค่า nginx ของคุณ (usally /etc/nginx/nginx.conf) หรือไฟล์ vhost config เปลี่ยนsendfileพารามิเตอร์เป็นoff:

sendfile  off;

ในขณะsendfileที่เป็นหัวใจสำคัญของชื่อเสียงของ Nginx (ประสิทธิภาพการให้บริการไฟล์คงที่ในระดับต่ำอย่างรวดเร็ว) มันอาจเป็นสิ่งที่ไม่ดีสำหรับการพัฒนาในท้องถิ่นเช่น Javascript ที่เปลี่ยนแปลงบ่อยและจำเป็นต้องโหลดซ้ำ อย่างไรก็ตาม Nginx sendfile นั้นฉลาดและอาจไม่ใช่ปัญหาของคนส่วนใหญ่ ตรวจสอบตัวเลือก "ปิดใช้งานแคช" ของเบราว์เซอร์เช่นกัน!


5
+1 แม้ว่าคำตอบควรอธิบายว่าทำไมจึงมีความจำเป็นแทนที่จะปล่อยให้ผู้อ่านค้นหา / อ่านคำถามที่ค้นหาการอ้างอิงได้อย่างมีประสิทธิภาพ ทำให้คำตอบนั้นเป็นของตัวเอง -> ดีกว่า
AD7six

2
นี่ดูเหมือนจะเป็นคำตอบสำหรับฉัน ปัญหาดูเหมือนว่าจะเกิดขึ้นกับการรวมกันของ Sendfile, VirtualBox และโฮสต์ OSX abitwiser.wordpress.com/2011/02/24/virtualbox-hates-sendfile forums.virtualbox.org/viewtopic.php?f=1&t=24905
Steve Bennett

sendfileใช้ได้แม้กับสภาพแวดล้อมการพัฒนาท้องถิ่น เป็น VirtualBox เท่านั้นที่ใช้งานไม่ได้ เหตุผลข้อใดข้อหนึ่ง (จากหลาย ๆ คน) ฉันแนะนำให้หลีกเลี่ยง VirtualBox ...
Michael Hampton

ขอบคุณสำหรับการบันทึกปัญหาที่แปลกประหลาดกับ Vagrant / VirtualBox / Ubuntu / Wordpress ฉันคาดเดาว่าสภาพแวดล้อม PROD ของฉันจะปลอดภัยเมื่อใช้ sendfile เป็นค่าเริ่มต้น
sonjz

แก้ปัญหาของฉันด้วย nginx และนักเทียบท่า
PascalTurbo

15

ตั้งค่าแท็กหมดอายุของคุณเป็น

expires off;

และไม่ควรตั้งค่าส่วนหัวที่หมดอายุให้เลยอาจเป็นเพราะไฟล์แคชของเบราว์เซอร์ของคุณไม่ถูกต้อง


น่าเสียดายที่ฉันได้ลองสิ่งนี้expires -1แล้วและพฤติกรรมก็ยังคงเหมือนเดิม
Olivier Chappe

เกี่ยวกับเบราว์เซอร์ฉันคิดถึงความเป็นไปได้นี้: ฉันพยายาม Chrome เป็นครั้งแรกและหลังจากแก้ไขไฟล์ที่เปิดขึ้นเป็นครั้งแรกใน Firefox: ฉันยังคงมีไฟล์เวอร์ชันแรกอยู่
Olivier Chappe

ส่วนหัวของการควบคุมแคชน่าจะเป็น CACHE-CONTROL: NO-CACHE
anthonysomerset

หรือลบส่วนหัวของการควบคุมแคชทั้งหมด - ขออภัยไม่สามารถแก้ไขความคิดเห็นก่อนหน้า
anthonysomerset

1
ใน Windows "หมดอายุ" ยังไม่ปิดการใช้งานการแคชไฟล์ html น่าผิดหวังอย่างยิ่งเมื่อฉันอัปเดตไฟล์ใน IDE ของฉัน แต่! $ #% nginx ให้บริการรุ่นเก่า
Dan Dascalescu

2

ถ้าไม่มีอะไรดังกล่าวข้างต้นจะช่วยให้และยังคง Nginx open_file_cacheส่งคืนเนื้อหาเก่าไฟล์ของคุณมันอาจจะมีปัญหาที่เกี่ยวข้องกับ

ดูเป็นข้อมูลอ้างอิง:


2

นี่เป็นข้อผิดพลาดเก่าใน VirtualBox (ดู: # 819 , # 9069 , # 12597 , # 14920 ) โดยที่ vboxvfs ดูเหมือนว่าจะมีปัญหาบางอย่างกับการเข้าถึง mmapped กับไฟล์ที่ซิงค์

สิ่งนี้อาจเกิดขึ้นเมื่อคุณแก้ไขไฟล์นอก VM และคุณคาดว่าจะเห็นการเปลี่ยนแปลงเดียวกันภายใน VM

เมื่อต้องการแก้ปัญหานี้คุณจำเป็นต้องปิดการใช้งานเคอร์เนล sendfile สนับสนุนการส่งไฟล์ไปยังลูกค้าโดยการปิดตัวเลือกEnableSendfile นี่เป็นปัญหาโดยเฉพาะอย่างยิ่งสำหรับไฟล์ที่เมาท์ NFS หรือ SMB

สำหรับNginx (เปลี่ยนในnginx.conf) เช่น

sendfile off;

คล้ายกับ Apache (ในhttpd.confหรือในไฟล์ vhosts) เช่น

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

หลังจากการเปลี่ยนแปลงโหลด Apache อีกครั้ง


โซลูชันที่เป็นไปได้อื่น ๆ คืออย่าลืมแก้ไขไฟล์บนโฮสต์หรือพยายามแก้ไขไฟล์เดียวกันอีกครั้ง แต่ภายใน VM


วิธีแก้ปัญหาอื่นรวมถึงการทิ้ง pagecache Linux เช่น

echo 1 > /proc/sys/vm/drop_caches

หรือเพื่อล้างแคชทุก ๆ วินาที (ตามโพสต์นี้ ) ลอง:

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

หมายเหตุ: หมายเลข 1 หมายถึงการเพิ่ม pagecache, 2 สำหรับ dentries และ inodes, 3 สำหรับ pagecache, denties และ inodes


ปัญหาข้างต้นสามารถทำซ้ำได้โดยโปรแกรม mmap-test ดังต่อไปนี้ดู: mmap-problem.c.


1

นี่สาย แต่ยังทำเครื่องหมายว่ายังไม่ได้ตอบดังนั้นฉันจะแทง เพียงแค่หัวเราะคิกคักคุณได้ลอง:

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

ยังไม่ได้ลองด้วยตัวเอง แต่ได้เรียนรู้ที่จะลองสิ่งนี้กับ Nginx ในคอนเทนเนอร์เซิร์ฟเวอร์เป็นครั้งคราวเมื่อฉันมีปัญหาคล้ายกับสิ่งนี้ ...

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.