共用方式為


第 2.2 部分 - 安裝 Nginx 並將其設定為反向 Proxy 伺服器

適用於: .NET Core 2.1、.NET Core 3.1、.NET 5

本文介紹如何安裝 Nginx,並將其設定為反向 Proxy 伺服器。

必要條件

若要遵循此部分中的練習,您必須建立一個 ASP.NET Core Web 應用程式並部署至 /var 資料夾。

此部分的目標

在上一個部分中,您已使用 .NET CLI 工具建立 ASP.NET Core Web 應用程式,並將應用程式部署至 /var 資料夾。 應用程式也設定為接聽埠 5000 的 HTTP 要求,並移除 HTTPS 重新導向。

此時,客戶端應該在連線到應用程式時提供埠號碼(例如, 。 http://localhost:5000 不過,這不是所需的行為。

我們在此部分中的目標如下:

  • 客戶端應該能夠巡覽,而不需要提供埠號碼。 例如,客戶端應該使用 http://localhost進行連線。
  • 如果 Web 應用程式因某種原因或電腦重新啟動之後停止,則應該會自動啟動。

在下一節中,您將使用 Nginx 作為 Proxy 伺服器,改為將對埠 80 的 HTTP 要求路由傳送至我們的 .NET 應用程式。 您也會將應用程式設定為自動啟動。

什麼是 Nginx?

Nginx 是熱門、輕量且快速的網頁伺服器。 它可以在Linux和 Windows 上執行,而且可以設定為反向 Proxy 伺服器。

什麼是精靈?

Nginx 會以精靈的形式執行。 精靈是背景中執行之服務的替代詞彙。 就像在 Windows 上執行的服務一樣,精靈可以設定為在啟動期間自動啟動。 您將設定 ASP.NET Core 應用程式以精靈身分執行。

使用APT安裝 Nginx

安裝 Nginx 很簡單。 sudo apt install nginx執行 命令以在Ubuntu虛擬機上安裝程式。

sudo 命令的螢幕快照。

安裝完成之後,請執行 whereis nginx 來探索程式安裝的位置。 您可以藉由檢查輸出來查看 Nginx 組態檔的位置。 下列螢幕快照顯示組態檔位於 /etc/nginx 資料夾中。

whereis 命令的螢幕快照。

注意

如果您執行 Ubuntu 或 Debian 以外的發行版,您可以從官方 Nginx 安裝檔中找到對等的套件管理員安裝命令或指示

使用 systemctl 管理服務

如果您沒有看到 Nginx 正在執行,您可以執行 來明確 sudo systemctl start nginx啟動它。 雖然此練習將示範 systemctl Nginx 的命令,但這些命令會用來設定 Web 應用程式以自動啟動作為精靈。

安裝完成之後,Nginx 已設定為自動啟動。 Nginx 會以精靈的形式執行。 您可以使用 systemctl 來檢查精靈的狀態。

systemctl命令可用來管理這類工作的「服務」,例如顯示服務的狀態,或啟動和停止它。 某些可用的參數為 start、stop、restart、enable、disable 和 status。 若要檢查 Nginx 的狀態,請執行 systemctl status nginx

systemctl 命令的螢幕快照。

此命令會產生一些有用的資訊。 如此螢幕快照所示,Nginx 處於 active (running) 狀態,而 Nginx 實例的進程標識碼為 8539。 另請注意 enabledvendor preset: enabled 語句。 Enabled 表示當機器重新啟動時,此精靈將會啟動,表示 vendor preset: enabled 安裝 Nginx 時預設會啟用 Nginx。 因此,Nginx 會在伺服器啟動時自動啟動。

測試 Nginx 安裝

根據預設,Nginx 會接聽埠 80。 因為它正在執行,所以當您流覽localhost時,應該能夠存取 Nginx 的主頁面。 使用 curl 執行 來測試 Nginx curl localhost。 下列螢幕快照中的黃色醒目提示文字會顯示 Nginx 預設網頁。 因此,Nginx 正在執行:

curl 命令的螢幕快照。

systemctl 命令選項

您可以使用 命令來管理 systemctl 服務或精靈。 啟動、停止或進行變更需要超級使用者存取權。 因此,您必須將 sudo 前置詞新增至這些命令。

重新啟動精靈

您可能必須不時重新啟動精靈。 若要重新啟動精靈,請執行 sudo systemctl restart <daemon_name>。 若要重新啟動 Nginx,請執行 sudo systemctl restart nginx。 請務必在執行此命令之前和之後檢查 Nginx 的狀態,以監視進程標識碼的變更。

停止精靈

若要停止精靈,請執行 sudo systemctl stop <daemon_name>。 若要停止 Nginx,請執行 sudo systemctl stop nginx,然後再次執行 systemctl status nginx 來檢查 Nginx 的狀態。 這次,服務會顯示為非作用中(死),但仍啟用。 這表示雖然服務未執行,但在重新啟動伺服器之後,它會自動啟動。

停止命令的螢幕快照。

注意

此命令 systemctl status 也會針對精靈顯示數行先前的記錄專案。

停止 Nginx 之後,請再次執行 curl localhost

注意

線上遭到拒絕,因為埠 80 上沒有任何接聽連入流量。

BuggyAmb localhost 的螢幕快照。

停用精靈

停用精靈與停止精靈不同。 停用的精靈可以執行,但在伺服器重新啟動之後,它不會自動啟動。 若要停用 Nginx 精靈,請執行 sudo systemctl disable nginx,然後檢查 Nginx 的狀態。

停用命令的螢幕快照。

此螢幕快照顯示 Nginx 未執行,且已停用。 這表示 Nginx 不會在重新啟動後自動啟動。

啟動精靈

若要啟動精靈,請執行 sudo systemctl start <daemon_name>。 若要啟動 Nginx,請執行 sudo systemctl start nginx,然後再次檢查服務的狀態。

啟動命令的螢幕快照。

此螢幕快照顯示 Nginx 已啟動,但仍停用。 雖然服務正在執行,但 Nginx 不會在重新啟動後自動啟動,因為它是停用的服務。

啟用精靈

啟用服務表示會在重新啟動後自動啟動。 若要啟用 Nginx,請執行 sudo systemctl enable nginx,然後再次檢查 Nginx 的狀態。

啟用命令的螢幕快照。

此螢幕快照顯示 Nginx 正在執行,而且會在伺服器重新啟動之後啟動。

將 Nginx 設定為反向 Proxy,以將要求路由傳送至您的 ASP.NET Core 應用程式

既然您已瞭解如何啟動、停止和重新啟動 Nginx 服務,接下來將 Nginx 設定為反向 Proxy,將埠 80 上提出的要求路由傳送至正在接聽埠 5000 的 ASP.NET Core 應用程式。

以下是必要的設定。 其中一些主要部分會反白顯示。

http {
  map $http_connection $connection_upgrade {
    "~*Upgrade" $http_connection;
    default keep-alive;
  }

  server {
    listen        80;
    server_name _;
    location / {
        proxy_pass         http://localhost:5000;
        proxy_http_version 1.1;
        proxy_set_header   Upgrade $http_upgrade;
        proxy_set_header   Connection $connection_upgrade;
        proxy_set_header   Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
    }
  }
}

此組態指出下列各項:

  • Nginx 會接聽埠 80 的所有要求(指示詞: listen 80)。
  • Nginx 會將要求路由傳送至 http://localhost:5000 (指示詞: proxy_pass http://localhost:5000

注意

程序 server_name _ 代碼中的行。 這會當做 catch-all 指示詞使用。 如果您想要深入瞭解server_name,請參閱官方檔

設定變更看起來很簡單。 我們將使用此程式碼來取代 server 組態檔中的指示詞區段。 但是組態檔在哪裡?

尋找正確的 Nginx 組態檔

主要 Nginx 組態檔為 /etc/nginx/nginx.conf。 若要檢查組態,請使用 cat /etc/nginx/nginx.conf 命令,然後搜尋伺服器指示詞。

cat 命令的螢幕快照。

捲動組態以找出伺服器指示詞。 您應該預期不會找到它。 我們可以將所需的組態變更放在組態檔內的某處。 不過,在理想情況下,您不想取代原始組態檔。 這是為了防止引入可能導致伺服器無法正確啟動的設定錯誤。 區 server 段不在主要組態檔中。 如果您持續捲動組態檔,您會發現有一些 include 指示詞。

include 命令的螢幕快照。

Include 指示詞可讓您更輕鬆地管理組態,方法是將它分割成要包含在主要組態檔中的區塊。 主要組態檔可以保持簡單,某些特定元件可以移至其他檔案。 這個螢幕快照中的醒目提示列指出下列事項:

  • Nginx 會從位於 /etc/nginx/conf.d 目錄中的每個 .conf 檔案 載入組 態。
  • Nginx 會從位於 /etc/nginx/sites-enabled 目錄的每個檔案 載入組態

如果您檢查這些目錄,在 /etc/nginx/conf.d找不到任何組態檔。 不過,已啟用 /etc/nginx/sites 的檔案中有一個

conf 命令的螢幕快照。

默認組態檔看起來像是主控我們要尋找的組態的主要候選專案。 如果您使用 來檢查 /etc/nginx/sites-enabled/default 檔案 cat /etc/nginx/sites-enabled/default,您會看到預設伺服器指示詞會放在下列程式代碼中。

默認信息的螢幕快照。

因此, 必須編輯 /etc/nginx/sites-enabled/default 檔案,才能變更組態。

使用vi編輯組態檔

您已瞭解如何編輯 Startup.cs檔案,以從 ASP.NET 管線移除 HTTPS 重新導向。 現在,您將再次使用vi來變更nginx組態檔。

提示

請一律備份您要變更的檔案。 如果在編輯之後發生問題,您可以使用該複本將檔案還原至其先前的狀態。 在此情況下,請執行 cp /etc/nginx/sites-enabled/default ~/nginx-default-backup 以將組態檔複製到主目錄。 備份檔案名稱將會是 nginx-default-backup。 請注意,備份並未在與源檔相同的目錄中進行。 這是因為 Nginx 會從該目錄載入所有組態檔,而且您不想載入兩個不同的伺服器指示詞版本來中斷設定。

執行 sudo vi /etc/nginx/sites-enabled/default 以編輯組態檔並取代伺服器指示詞,如下列螢幕快照所示。

vi 命令的螢幕快照。

以下是使用vi編輯檔案的一些秘訣和訣竅:

  • 您可以使用箭頭鍵來向上和向下捲動。
  • 若要進入編輯模式,請按 InsertI 鍵。 當您處於編輯模式時,左下角會有一則 --INSERT-- 訊息。
  • 在編輯模式中,您可以使用鍵盤一次刪除一個字元。
  • 在編輯模式中,複製和貼上作業會與大部分終端機搭配運作。 因此,您可以從本文複製內容,並將其貼到vi中。
  • 若要結束編輯模式,請按 Esc 鍵。
  • 您可以在一般模式中更輕鬆地刪除行。 在一般模式中,移至您要刪除的行開頭,然後輸入 dd。 此命令 dd 會刪除整行。 您也可以輸入 5dd 以一次刪除五行。 不過,應謹慎使用此選項,以避免刪除額外的內容。
  • 如何在 Vim / Vi 文章中刪除行是一個很好的文章,瞭解如何刪除 vi 中的多行。
  • 若要結束vi並儲存變更,請輸入 :wq!,然後按 Enter。 在這裡,冒號 (:) 表示您正在執行命令、 w 表示寫入變更、 q 表示結束,以及 ! 表示覆寫變更。
  • 若要結束而不儲存變更,請輸入 :q!,然後按 Enter

變更現在已儲存,您必須重新啟動 Nginx 服務,這些變更才會生效。 重新啟動服務之前,您可以執行 sudo nginx -t 命令來測試組態檔。 當此命令執行時,Nginx 會檢查組態檔語法,然後嘗試開啟組態檔中所參考的檔案。

t 命令的螢幕快照。

如您所見,已變更的組態檔似乎正確。

我們必須重新啟動 Nginx,變更才會生效:

sudo systemctl restart nginx

重新啟動之後,當您對 http://localhost 提出要求時,您預期會看到來自 ASP.NET Core 應用程式的回應,因為 Nginx 應該做為對埠 80 所提出要求的反向 Proxy。

重新啟動 Nginx 服務,讓變更生效,然後執行 curl localhost來向 localhost 提出要求。 不過,此命令將會失敗。 下一個步驟是執行 wget localhost,然後搜尋問題來源的一些提示。

wget 命令的螢幕快照。

針對 Nginx Proxy 問題進行疑難解答

在上一個螢幕快照中,您會看到此資訊:

Resolving localhost (localhost)... 127.0.0.1  
Connecting to localhost (localhost)|127.0.0.1|:80... connected.  
HTTP request sent, awaiting response... 502 Bad Gateway  
2020-12-27 21:15:53 ERROR 502: Bad Gateway.

第一行和第二行表示您可以解析 localhost,並在套接字上 127.0.0.1:80 連線。 因此,Nginx 應該正在執行。 若要確認這一點,您可以執行 systemctl status nginx 命令。

第三行表示問題的來源。 您會收到 HTTP 502 不正確的閘道 錯誤訊息。 HTTP 502 不正確的閘道 與 Proxy 相關。 這表示反向 Proxy 無法連線到後端應用程式。 在此情況下,您的 ASP.NET Core Web 應用程式應該針對要求在埠 5000 上執行並接聽。 我們應該檢查 Web 應用程式是否也正在執行。

若要開始疑難解答,請執行與之前相同的 netstat 命令。 這次,請使用 grep 來篩選應用程式的埠 5000。 然後,執行 netstat -tlp | grep 5000

netstat 命令的螢幕快照。

此範例輸出表示埠 5000 上沒有接聽任何內容。 因此,這是來自 Nginx 的 HTTP 502 回應的原因,因為它找不到在埠 5000 上接聽的進程。

解決方案是啟動您的 ASP.NET Core 應用程式。 不過,在進行進一步之前,您可以檢閱另一種方法來針對此問題進行疑難解答。 並非所有問題都很容易修正,只要查看幾行記錄內容並找出根本原因即可。 有時候,您必須深入探討其他系統和應用程序記錄。

由於您在Linux中設定 ASP.NET Core應用程式時,與 Nginx 密切合作,因此建議您瞭解 Nginx 和作業系統所提供的記錄類型以進行疑難解答。

檢查 Nginx 記錄

如果您再次執行 cat /etc/nginx/nginx.conf ,然後尋找 logging settings,您應該注意到下列事項。

記錄信息的螢幕快照。

這會顯示 Nginx 有兩種記錄:存取記錄和錯誤記錄。 這些會儲存在 /var/log/nginx/ 目錄中。

存取記錄類似於 IIS 記錄檔。 快速檢查內容會顯示其類似下列螢幕快照。

存取命令的螢幕快照。

存取記錄不會顯示您已經知道的 HTTP 502 回應狀態以外的新資訊。 您也可以執行 cat /var/log/nginx/error.log來檢查錯誤記錄檔。 這些揭示了更多關於問題的原因。

錯誤信息的螢幕快照。

指示很清楚:Nginx 可以從用戶端取得要求,但無法連線到 upstream 位於 http://127.0.0.1:5000 和的 ASP.NET Core 應用程式,而應該在該埠上執行和接聽。

因應措施

若要解決此問題,請手動啟動您的 ASP.NET Core 應用程式。 使用第二個終端機會話連線到伺服器,然後像以前一樣執行 ASP.NET Core 應用程式。

aspnet 信息的螢幕快照。

當您的 ASP.NET Core 應用程式正在執行時,請切換至其他終端機會話,然後執行相同的 curl localhost 命令。 現在,您可以存取在 Nginx 後方執行的 ASP.NET Core 應用程式。 下列螢幕快照顯示您向 localhost 提出要求、Nginx 處理要求並路由傳送至後端應用程式,而且您收到來自 ASP.NET Core 應用程式的回應。

curllocalhost 命令的螢幕快照。

您現在已設定 Nginx 做為在 Linux 中執行之 ASP.NET Core 應用程式的反向 Proxy。

不過,如果 ASP.NET Core 應用程式在重新啟動後未啟動,結果會是什麼? 如果 Web 應用程式當機,而且直到您注意到它未執行,才會啟動,會發生什麼情況? 每次重新啟動進程終止之後,您應該啟動 ASP.NET Core 應用程式嗎?

下一步

第 2.3 部分 - 設定 ASP.NET Core 應用程式以自動啟動

協力廠商資訊免責聲明

本文提及的協力廠商產品是由與 Microsoft 無關的獨立廠商所製造。 Microsoft 不以默示或其他方式,提供與這些產品的效能或可靠性有關的擔保。