通过 nginx 提供动态缓存图像

通过 nginx 提供动态缓存图像

我想要提供图像的缩略图,并且这些缩略图是按需生成的,写入磁盘,然后我想要将它们交给 nginx 来提供。

我的缩略图根文件夹是/var/www/images。当我收到 请求时/thumb/post1/image1.jpg,我希望像这样处理它:

  1. 如果图像存在于中/var/www/images/thumb/post1/image1.jpg,则直接提供该图像。
  2. 如果图像不存在,则需要生成,因此将请求传递给 API @backend
  3. API 生成图像并将其写入缩略图文件夹,然后使用标X-Accel-Redirect头将其路径交回给 nginx。
  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,但是,我在两个location指令中都覆盖了它,并且没有顶级try_files

但是,这不起作用。丢失图片的请求不会发送到 API,但丢失图片的后备会发送到 API!如果我删除后备,请求被发送到 API,但随后交接x-accel-redirect失败,即使文件现在存在;当缩略图确实存在时,nginx 不会为其提供服务——它只是再次访问 API。

这该如何配置?

答案1

你的try_files说法不对,命名位置需要作为最后一个参数。另外,404 响应是由块生成的,与块中的语句location @backend无关。try_fileslocation /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;
}

相关内容