Apache-2.2

來自後端的 301 的 nginx 負載平衡問題

  • January 27, 2017

我遇到了一個奇怪的問題,我不確定這是配置問題還是 nginx 中的錯誤。我的設置是具有 Apache2 後端伺服器的 nginx 反向代理。負載均衡器非常基本,類似於wiki 中的範例,例如簡化:

http {
 upstream myproject {
   server 127.0.0.1:8000;
 }

 server {
   listen 80;
   location / {
     proxy_pass http://myproject;
   }
 }
}

現在,例如,當我嘗試在 Apache 中請求一個目錄時,就會出現一個問題,而 url 末尾沒有斜杠。例如,客戶端請求:

http://apache.myserver.com/somedirectory

Apache 將回复 HTTP 302 以將客戶端重定向到

http://apache.myserver.com/somedirectory/

注意 url 末尾有一個斜杠,說明它是一個目錄。另請注意,Apache 通過在重定向標頭中使用傳入的請求主機名是“智能的”。到目前為止一切都很好。但是,當使用帶有負載平衡的 nginx 時,此 301 被發送到客戶端,而不會將 nginx 上游名稱轉換回實際的伺服器/域。因此客戶端將收到以下資訊:

GET http://nginx.myserver.com/somedirectory
HTTP 301 Moved Permanently
...
Location: http://myproject:8000/somedirectory/

myproject是 nginx 上游後端的名稱。它不是客戶端可以解析的實際主機。在我看來,客戶端應該被重定向到

http://nginx.myserver.com/somedirectory/  

即上游後端的名稱應該在響應頭中被替換。這是 nginx 中的錯誤還是我做錯了什麼?

原來 nginx 有很多代理重定向選項來處理這類問題。我最終使用了這樣的東西:

location / {
   proxy_pass  http://myproject;
   proxy_set_header Host myproject;
   proxy_redirect http://myproject/ $scheme://$host/;
   proxy_redirect http://myproject:8000/ $scheme://$host/;
}

這基本上用 $host 替換了上游名稱並刪除了埠。這對我來說很有效,因為我在 HTTP/HTTPS 的預設埠上託管 nginx。如果 nginx 在非預設埠上執行,則需要這樣的東西:

   proxy_redirect http://myproject/ $scheme://$host:$server_port/;
   proxy_redirect http://myproject:8000/ $scheme://$host:$server_port/;

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