แสดงรูปภาพที่แคชแบบไดนามิกจาก nginx

Sep 19 2020

ฉันต้องการแสดงภาพขนาดย่อสำหรับรูปภาพและภาพขนาดย่อเหล่านี้ถูกสร้างขึ้นตามความต้องการเขียนลงดิสก์จากนั้นฉันต้องการส่งให้ nginx แสดง

โฟลเดอร์รูทของฉันสำหรับภาพขนาดย่อคือ/var/www/images. เมื่อได้รับคำขอ/thumb/post1/image1.jpgฉันต้องการดำเนินการดังนี้:

  1. หากมีรูปภาพอยู่/var/www/images/thumb/post1/image1.jpgให้แสดงโดยตรง
  2. หากภาพที่ไม่ได้มีจะต้องสร้างเพื่อให้ผ่านการร้องขอไปยัง API @backendที่
  3. API สร้างภาพและเขียนลงในโฟลเดอร์ภาพขนาดย่อจากนั้นส่งเส้นทางไปยัง nginx โดยใช้X-Accel-Redirectส่วนหัว
  4. nginx เริ่มการประมวลผลใหม่ในขั้นตอนที่ 1 ซึ่งจะสำเร็จเนื่องจากขณะนี้มีไฟล์อยู่
  5. หากไม่มีรายการที่ขอนิ้วหัวแม่มือ API จะส่งคืน 404 และ nginx ควรแสดงภาพตัวยึดที่อยู่/var/www/images/missing.pngแทน

การกำหนดค่า nginx ของฉันมีลักษณะดังนี้:

upstream api {
  server localhost:7440 fail_timeout=0;
}

server {
  root /var/www/www.example.com/public;

  location / {
    try_files $uri @backend; } location /thumb { root /var/www/images; try_files $uri @backend /missing.png;
  }

  location @backend {
    root /var/www/api.example.com/public;
    proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $http_host;
    proxy_set_header X-NginX-Proxy true;

    proxy_redirect off;
    proxy_pass http://api;

    #For websocket compatibility
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
  }
}

ภาพขนาดย่อของฉันถูกเก็บไว้นอกโฟลเดอร์โปรเจ็กต์ดังนั้นฉันจึงต้องการrootคำสั่งใน/thumbตำแหน่งเพื่อให้มองหารูปภาพนั้น /สถานที่จัดการการร้องขอ API และสินทรัพย์คงที่อื่น ๆ และและ/thumbสถานที่ไม่เหมือนกัน missing.pngแต่ยังมีทางเลือกที่จะ

หนึ่งมุมแหลม: ด้วยเหตุผลทางประวัติศาสตร์โดยรวมของฉันrootโฟลเดอร์จะไม่เหมือนกันเป็นหนึ่งที่ใช้โดยฉัน@backendตั้งชื่อ แต่ฉันเอาชนะว่าในทั้งสองสั่งและไม่มีระดับบนสุดlocationtry_files

อย่างไรก็ตามไม่ได้ผล คำขอสำหรับรูปภาพที่หายไปจะไม่ถูกส่งไปยัง API แต่มีทางเลือกสำหรับรูปภาพที่หายไป! หากฉันลบทางเลือกคำขอจะถูกส่งไปยัง API แต่ Handoff จะx-accel-redirectล้มเหลวแม้ว่าจะมีไฟล์อยู่แล้วก็ตาม เมื่อมีอิมเมจนิ้วหัวแม่มืออยู่ nginx จะไม่แสดงมันเพียงแค่กด API อีกครั้ง

ควรกำหนดค่าอย่างไร

คำตอบ

RichardSmith Sep 19 2020 at 13:38

try_filesคำสั่งของคุณไม่ถูกต้องตำแหน่งที่ระบุชื่อจะต้องเป็นพารามิเตอร์สุดท้าย นอกจากนี้การตอบสนอง 404 ถูกสร้างขึ้นโดยlocation @backendบล็อกและไม่มีส่วนเกี่ยวข้องกับtry_filesคำสั่งในlocation /thumbบล็อก

คุณควรพยายามproxy_intercept_errorsและerror_pageจัดการกับการตอบสนอง 404 จากแบ็กเอนด์

ตัวอย่างเช่น:

location / {
    try_files $uri @backend1; } location /thumb { root /var/www/images; try_files $uri @backend2;
}

proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

location @backend1 {
    proxy_pass http://api;
}
location @backend2 {
    proxy_intercept_errors on;
    error_page 404 /missing.png;
    proxy_pass http://api;
}