Nginx

帶有嵌套代理的 Nginx 自定義 502 頁面

  • May 7, 2020

我知道如何為上游錯誤創建自定義 502 頁面,並且多次沒有問題,但是在這種特殊情況下,一個代理響應被傳遞給另一個代理,我找不到正確的配置。

一般的工作流程是這樣的:使用者請求圖片的縮略圖,nginx 將此請求代理到圖片儲存。如果 storage 返回 404,則 nginx 將此請求代理到應用伺服器,應用伺服器生成帶有請求 URI 的縮略圖並返回程式碼 200,通過 nginx 傳遞給使用者。

但是,如果使用者請求完全不存在圖片的縮略圖,則應用伺服器返回 502。在這種情況下,我想顯示一個自定義頁面,而不是內置的 nginx“502 Bad Gateway”。

正如我在開始時提到的,我知道如何創建自定義 502 頁面,但我認為這種具有雙重代理的特殊複雜設置需要一些我找不到的額外配置 :( 我嘗試了一個帶有內部選項的位置,我我嘗試了一個帶有指向 html 頁面的直接 URL 的位置,我嘗試了“@”位置,但 nginx 總是顯示其內置頁面。文件 502.html 和 502x.html 都存在於 /var/www/html 中並且是可讀的通過 nginx:

ll /var/www/html
total 20
drwxr-xr-x 2 root root 4096 May  3 11:21 ./
drwxr-xr-x 4 root root 4096 Mar 24 11:50 ../
-rw-r--r-- 1 root root   36 Apr 28 10:49 502.html
-rw-r--r-- 1 root root   36 May  3 11:21 502x.html

Nginx 配置:

server {
listen 443 ssl http2;
server_name cdn.domain.tld;

ssl_certificate /etc/letsencrypt/live/cdn.domain.tld/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/cdn.domain.tld/privkey.pem;

client_max_body_size 10m;

client_body_buffer_size 128k;
proxy_connect_timeout 75;
proxy_send_timeout 300;
proxy_read_timeout 500;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
proxy_http_version 1.1;
proxy_buffering on;
proxy_redirect off;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

#locations for redirection of 502 response received from thumbnail generator. Not working :(
#error_page 502  @502;
#error_page 502  https://cdn.domain.tld/502x.html;
error_page 502  /502.html;
location =/502.html {
  root /var/www/html;
  internal;
}
location @502 {
  root /var/www/html;
  try_files /502x.html 502;
}
location = /502x.html {
  root /var/www/html;
  index 502x.html;
}

location  / {
   proxy_pass http://192.168.10.5/thumbs$request_uri;

   #Sets caching time for different response codes. If only caching time is specified  then only 200, 301, and 302 responses are cached.
   proxy_cache_valid 30m;

   add_header X-Proxy-Thumbs-Cache $upstream_cache_status;

   #intercept 404 from backend
   #from nginx docs:
   #If an error response is processed by a proxied server or a FastCGI/uwsgi/SCGI/gRPC server,.
   #and the server may return different response codes (e.g., 200, 302, 401 or 404), it is possible to respond with the code it returns (equal sign does that)
   #So we proxy 404 to app which generates thumbnail and returns it with 200 code
   proxy_intercept_errors on;
   error_page 404 = @not-found;

   access_log /var/log/nginx/cdn.access.log cachelog;
   error_log /var/log/nginx/cdn.error.log;
}

location @not-found {
  proxy_pass http://192.168.10.12/thumbgen?key=$request_uri;

  add_header X-Proxy-Thumbs-Cache2 $upstream_cache_status;

  proxy_intercept_errors on;

  access_log /var/log/nginx/cdn-404.access.log cachelog;
  error_log /var/log/nginx/cdn-404.error.log;
}

}

我在這個執行緒中找到了答案:http: //mailman.nginx.org/pipermail/nginx/2011-July/027966.html

我不得不添加**recursive_error_pages ;**進入伺服器部分,所以我的最終配置如下所示:

server {
   listen 443 ssl http2;
   server_name cdn.domain.tld;

   ssl_certificate /etc/letsencrypt/live/cdn.domain.tld/fullchain.pem;
   ssl_certificate_key /etc/letsencrypt/live/cdn.domain.tld/privkey.pem;

   client_max_body_size 10m;

   client_body_buffer_size 128k;
   proxy_connect_timeout 75;
   proxy_send_timeout 300;
   proxy_read_timeout 500;
   proxy_buffer_size 4k;
   proxy_buffers 4 32k;
   proxy_busy_buffers_size 64k;
   proxy_temp_file_write_size 64k;
   proxy_http_version 1.1;
   proxy_buffering on;
   proxy_redirect off;

   proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
   proxy_set_header X-Forwarded-Proto $scheme;

   #we need this to enable redirection of 502 code inside @not-found location
   recursive_error_pages on;

   #location for redirection of 502 responses received from thumbnail generator.
   location =/502.html {
      root /var/www/html;
      internal;
   }

   location  / {
       proxy_pass http://192.168.10.5/thumbs$request_uri;

       #Sets caching time for different response codes. If only caching time is specified  then only 200, 301, and 302 responses are cached.
       proxy_cache_valid 30m;

       add_header X-Proxy-Thumbs-Cache $upstream_cache_status;

       #intercept 404 from backend
       #from nginx docs:
       #If an error response is processed by a proxied server or a FastCGI/uwsgi/SCGI/gRPC server,.
       #and the server may return different response codes (e.g., 200, 302, 401 or 404), it is possible to respond with the code it returns (equal sign does that)
       #So we proxy 404 to app which generates thumbnail and returns it with 200 code
       proxy_intercept_errors on;
       error_page 404 = @not-found;

       access_log /var/log/nginx/cdn.access.log cachelog;
       error_log /var/log/nginx/cdn.error.log;
   }

   location @not-found {
      proxy_pass http://192.168.10.12/thumbgen?key=$request_uri;

      add_header X-Proxy-Thumbs-Cache2 $upstream_cache_status;

      proxy_intercept_errors on;
      error_page 502  /502.html;

      access_log /var/log/nginx/cdn-404.access.log cachelog;
      error_log /var/log/nginx/cdn-404.error.log;
   }
}

引用自:https://serverfault.com/questions/1015934