Nginx

擷取上游向下 (502) 錯誤並顯示自定義錯誤頁面

  • April 5, 2015

這個問題應該很久以前就已經回答了,但是儘管閱讀了許多常見答案,但我似乎無法弄清楚,有人可以指出為什麼我的配置不起作用嗎?

目標:當上游 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兩者或其中之一serverlocation阻止。
  • 我已經在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;
}

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