Nginx
擷取上游向下 (502) 錯誤並顯示自定義錯誤頁面
這個問題應該很久以前就已經回答了,但是儘管閱讀了許多常見答案,但我似乎無法弄清楚,有人可以指出為什麼我的配置不起作用嗎?
目標:當上游 server_api 關閉時(例如,它的工作程序已經崩潰),我希望 nginx 顯示我的自定義錯誤頁面。
我的配置:
location @server { proxy_pass http://server_api; proxy_redirect off; ... proxy_intercept_errors on; error_page 502 /error-502.html; } error_page 502 /error-502.html; location = /error-502.html { internal; root /srv/my-server/html; }
我的步驟:
- 我已經
/srv/my-server/html/error-502.html
準備好我的靜態錯誤頁面,與其他靜態資產具有相同的權限和所有者。- 我已經停止了我的上游服務,並看到
[error] 2359#0: *25 connect() failed (111: Connection refused) while connecting to upstream
出現在日誌中。- 現在我嘗試讓我的自定義錯誤頁面顯示 502 錯誤。
- 我試過設置
error_page
兩者或其中之一server
或location
阻止。- 我已經在or塊中嘗試
error_page
過;proxy_intercept_errors on``location``server
他們似乎都沒有說服 nginx 顯示我的錯誤頁面。為什麼不?我錯過了什麼?
感謝賈斯汀和邁克爾為我指明了正確的方向,這確實是一個導致我麻煩的位置塊,特別是:
location / { try_files $uri $uri/ @server; error_page 403 = @server; }
基本上,我試圖變得聰明並擷取
$uri/
錯誤(當您嘗試訪問存在但沒有索引文件或自動索引的文件夾時會發生 403)並將其重定向到@server
塊。但
try_files $uri $uri/ @server;
一個人還不夠嗎?想像一下你試圖訪問
http://example.com/
,nginx 會說,哦,這個文件夾存在(它是你的root
)但沒有找到索引,然後拋出 403 而不是傳遞到@server
塊上。因此我的 403 解決方案,但我沒有意識到它是有代價的:這意味著 nginx 已經擷取了一個錯誤並
error_page
在同一個location
塊中使用它來處理它(通過將它傳遞給@server
)。將此與我在問題中的測試相結合,它表明 nginx(v1.7.x)此時將忽略進一步
error_page
的指令並改用預設的 502。有趣的部分:我們如何解決這個問題?
我的解決方案是設置一個完全匹配的根路由,現在不再需要在根上擷取 403,並且
error_page
可以按預期工作。error_page 502 /error-502.html; location = /error-502.html { internal; root /srv/example.com/html; } location = / { try_files $uri @server; } location / { try_files $uri $uri/ @server; }