Nginx

連接到上游時 nginx 連接被拒絕

  • November 24, 2018

我有一台伺服器,在其上部署了 API(Sinatra)。我在埠 9292 上執行該 API 並向其代理請求。

我還需要部署一個靜態 javascript 文件及其支持資源。我在同一台伺服器上這樣做。

以下所有資訊均已匿名化。

API 訪問端點是這樣的:

server {
   listen 80;
   server_name api.myapp.com;

   location / {
           proxy_pass http://localhost:9292;
   }
}

我為 JS 提供服務的端點是:

server {
   listen 80;
   server_name xsa.myapp.com;

   location / {
           root /data/mydir/xsa;
   }
}

您在下面的錯誤中看到的“localhost:3003”伺服器是我引用 JS 的地方。

2018/11/23 23:31:27 [error] 18720#0: *32 connect() failed 
(111: Connection refused) while connecting to upstream, 
client: 255.255.255.7, server: api.myapp.com,
request: "GET /api/v1/sub/sub_ABCXYZ/info?token%3D56f51132-
406b-4e06-a600-7379876446ed HTTP/1.1", upstream:
"http://[::1]:9292/api/v1/sub/sub_ABCXYZ/info?token%3D56f51132
-406b-4e06-a600-7379876446ed", host: "api.myapp.com",
referrer: "http://xsa.myapp.com/src/selector.html?
mfid=sub_ABCXYZ&location=http://localhost:3003/"

回顧一下:

  • 帶有埠 9292 的 VM“x”上的 Sinatra API
  • VM“x”上的 nginx 伺服器在埠 80 上為 API 提供代理,以處理進入“api.myapp.com”的請求
  • 同一個 nginx 伺服器還在埠 80 上為進入“xsa.myapp.com”的請求提供一個 javascript 文件

我可以在瀏覽器中很好地查看 JS,所以它確實被提供了。正是它在實例化時執行的動態內容導致了錯誤。

我還可以看到 9292 上的 Sinatra 伺服器確實收到了請求並返回了 200。看來問題出在此之後。所以它甚至看起來不像上游連接實際上被拒絕了。我已經仔細檢查了這個回復與 JS 在本地提供(並且有效)時的回复完全相同。

*** 更新 ***

即使 JS 在本地提供並正常工作,“連接被拒絕”錯誤實際上也會發生,因此看起來該錯誤是一個紅鯡魚。

您收到此錯誤消息是因為您的 Sinatra 應用程序沒有偵聽 localhost 的預設 IPv6 地址,::1而是偵聽舊版 IPv4 地址127.0.0.1.

因為您指定您的 nginx 上游是localhost,所以 nginx 首先嘗試 IPv6 地址,但是由於您的應用伺服器沒有偵聽此地址,所以 nginx 會收到拒絕連接。然後它在 IPv4 上重試連接,連接成功,並為您的應用程序提供服務。

因為這引入了性能問題,並且由於 IPv6 比已棄用的 IPv4 更受青睞,所以您應該重新配置您的 Sinatra 應用程序以偵聽 IPv6。例如,

set :bind, '::1'

特別是,您不應綁定到 127.0.0.1。

您也可以只刪除綁定主機,因為預設情況下,如果您使用的是瘦(就像您應該在產品中一樣)或 WEBrick(在開發中,如果您忘記 gem install thin),它將在 IPv6 localhost 上偵聽。

(並且在相關說明中,您已明確配置 nginx偵聽 IPv6,這將在以後或什至現在給您帶來類似的問題。您也應該修復它,而您正在使用它。)

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