![带有嵌套代理的 Nginx 自定义 502 页面](https://linux22.com/image/752031/%E5%B8%A6%E6%9C%89%E5%B5%8C%E5%A5%97%E4%BB%A3%E7%90%86%E7%9A%84%20Nginx%20%E8%87%AA%E5%AE%9A%E4%B9%89%20502%20%E9%A1%B5%E9%9D%A2.png)
我知道如何为上游错误创建自定义 502 页面,并且多次顺利地完成了此操作,但是在这种特殊情况下,一个代理响应被传递给另一个代理,我找不到正确的配置。
一般工作流程如下:用户请求图片缩略图,nginx 将此请求代理到图片存储。如果存储返回 404,则 nginx 将此请求代理到应用服务器,应用服务器根据请求的 URI 生成缩略图,并以代码 200 返回,并通过 nginx 传递给用户。
但是,如果用户请求完全不存在的图片的缩略图,应用服务器将返回 502。在这种情况下,我想显示自定义页面,而不是内置的 nginx“502 Bad Gateway”。
正如我在开头提到的,我知道如何创建自定义 502 页面,但我认为这种带有双代理的特殊复杂设置需要一些我找不到的额外配置 :( 我尝试过一个位置内部的选项,我尝试过直接将 URL 指向 html 页面的 location,也尝试过使用“@” localtion,但 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;
}
}
答案1
我在这个帖子中找到了答案:http://mailman.nginx.org/pipermail/nginx/2011-July/027966.html
我必须补充一下递归错误页面开启;进入服务器部分,所以我的最终配置如下所示:
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;
}
}