.NET Core 在 IIS、Windows 服務、Linux 上的部署方式


隨着微軟不斷的發布更新 .NET Core 新版本,使用該技術的小伙伴們越來越多。主要還是因為兩點:跨平台部署 和 開源。
當然只有 ASP.NET Core 網站 和 控制台程序 可以進行跨平台部署。目前 .NET Core 開發的 WinForm 和 WPF 仍然只能運行在 Windows 平台上,希望未來也能夠支持跨平台吧。

雖然 .NET Core 開發好的網站和控制台服務可以部署在 Windows 上,但是我還是建議大家以后無論是測試環境部署,還是生產環境部署,盡量使用 Linux 部署,原因如下:

  • .NET Core 部署在 Linux 上是不可逆轉的大趨勢,未來絕大部分場景都會以微服務的方式部署在 Docker 上,而 Docker 只能運行在 Linux 服務器上。雖然 Windows 也能夠安裝 Docker ,但是本質上還是在 Windows 上的虛擬機上運行 Linux ,然后在虛擬機的 Linux 上運行 Docker ,性能效率肯定大大折扣。
  • 如果生產環境使用 Linux 部署,那么測試環境最好也是 Linux。因為 Windows 上開發好的 .NET Core 程序即使在 Windows 上運行很好,但是在 Linux 上難免會產生文件路徑問題,以及其它一些小問題。因此需要提前發現和修復。

當前微軟發布的最新 .NET Core 的版本是 .NET5 ,目前 .NET6 還處於預覽版。我們就以 .NET5 開發好的網站為例,分別在 Windows 平台上的 IIS 和 Windows Service 上,以及 CentOS7 上介紹如何進行部署。

一、部署前提條件

我們先 使用 VS2019 基於 .NET5 創建一個默認網站樣例:

1 創建新項目,選擇 ASP.NET Core Web 應用(模型-視圖-控制器)

image

2 然后一直點擊下一步,可以考慮取消勾選 HTTPS,然后一直下一步,創建出如下圖所示的代碼結構:

image

3 為了能夠自定義網站啟動時的端口,我們需要修改兩個地方,appsettings.json 和 Program.cs

appsettings.json 配置文件修改后的代碼如下:

{
    "Logging": {
        "LogLevel": {
            "Default": "Information",
            "Microsoft": "Warning",
            "Microsoft.Hosting.Lifetime": "Information"
        }
    },
    "AllowedHosts": "*",
    //這個是我新增加的配置節:網站啟動時的端口
    "ListenPort": "http://*:9090"
}

Program.cs 文件修改后的代碼如下:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    //這個是我新增加的代碼,作用是在網站啟動前加載 appsettings.json 配置文件
    public static IConfiguration Config = 
        (new ConfigurationBuilder()).SetBasePath(Environment.CurrentDirectory)
        .AddJsonFile("appsettings.json", false, true).Build();

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder =>
        {
            //我在這里增加了代碼 UseUrls(要監聽的網站地址端口)
            //格式類似為:UseUrls(Http://*:9090)
	    webBuilder.UseUrls(Config["ListenPort"]).UseStartup<Startup>();
        });
}

4 選擇使用控制台的方式啟動(默認使用的是 IIS Express 方式啟動,端口是 5000)。

image

image

控制台窗口啟動后,可以看到網站啟動的端口,如果是配置的端口,則表明上面新增加的代碼編寫的沒有問題。
(備注:從 appsetting.json 中的 ListenPort 配置節中讀取的啟動端口的配置值為:"http://*:9090")
如上圖所示,此時使用瀏覽器訪問 localhost:9090 或者 127.0.0.1:9090 就可以看到網頁。

5 采用框架依賴、可移植的方式發布網站程序

image

發布后的文件如下圖所示:

image
到此為止,部署前的准備工作已經完畢。

二、在 IIS 上部署

這里我們使用服務器操作系統 Windows Server 2019 進行演示,並且服務器已經安裝好了 IIS
(因為篇幅有限,服務器上 IIS 的安裝不是本篇博客的重點,這里就不介紹了)

我們首先將發布后的文件,復制到服務器上,假設復制到 C 盤的 CoreDemoWeb 文件夾。
(文件夾中 web.config 是必須的,exe 文件不是必須文件,可以刪除掉)

1 安裝 dotnet-hosting-xxx-win.exe

在 IIS 上部署 .NET Core 網站,只需要安裝着一個軟件即可,不需要安裝其它額外的軟件。

該軟件的下載地址為:https://dotnet.microsoft.com/download/dotnet

進入網頁后,點擊具體的 .NET Core 版本,這里我選擇 .NET 5.0,點擊后進入詳細頁面:

image

上面有這樣一句話:
On Windows, we recommend installing the Hosting bundle, which includes the .NET Runtime and IIS support 。
這句話的意思表明:
只需要下載安裝 Hosting Bundle 這一個軟件就可以了,它已經包含了 .NET Core 運行時 和 對 IIS 的支持。

下載並安裝好軟件后,打開 IIS 管理窗口,在右側點擊 “模塊

image

然后會發現模塊列表中,多出一項:AspNetCoreModuleV2 ,看到這個表明已經安裝成功。

image

2 在 IIS 上部署 .NET 5 網站

打開 IIS 管理器,新建網站,在彈出框中填寫相應的內容

image

應用程序池,不需要特意將應用程序池選擇無托管,因此創建了應用程序池后,不需要進行任何操作。

這里隨便綁定的一個域名 www.testweb.com ,目的是為了使用 80 端口。
(我們在上面創建的網站示例中,可以在配置文件中指定具體的啟動端口,
但是如果部署在 IIS 上的話,那么就使用 IIS 新建網站時指定的端口。)

最后點擊 確定 按鈕,網站就創建好了。

3 瀏覽網站驗證部署效果

我的服務器 ip 地址是:192.168.174.128

我的本機 ip 地址是:192.168.174.1

我們修改一下 hosts 文件,將 www.testweb.com 這個域名指向服務器 ip 192.168.174.128 即可。
(如果你想在服務器上使用瀏覽器訪問剛剛部署好的網站,就在服務器的 hosts 文件添加域名指向記錄,
當然如果想在本機使用瀏覽器訪問網站,就在本機的 hosts 文件中添加域名指向記錄即可)

如果你的操作系統安裝在 C 盤,那么 hosts 文件就在 C:\Windows\System32\drivers\etc 文件夾內。

我用記事本打開本機的 hosts 文件,添加如下域名指向記錄

image

然后打開瀏覽器訪問 www.testweb.com,網頁顯示如下,大功告成,(#^.^#)

image

三、在 Windows Service 上部署

我們再復制一份發布后的文件到服務器上,假設復制到 C 盤的 CoreDemoService 文件夾。
(文件夾中 web.config 和 exe 文件都不是必須文件,可以刪除掉)

1 安裝 .NET5 的 SDK 或 ASP.NET Core Runtime

軟件下載地址同上:https://dotnet.microsoft.com/download/dotnet

進入網頁后,點擊具體的 .NET Core 版本,這里我選擇 .NET 5.0,點擊后進入詳細頁面:

SDK 下載界面如下:(因為我的服務器操作系統是 64 位,所以我下載 64 位的 SDK)

image

ASP.NET Core Runtime 下載界面如下:(因為我的服務器操作系統是 64 位,所以我下載 64 位的 SDK)

image

這兩個軟件,安裝其中一個即可,我個人建議安裝 SDK,因為 SDK 包含的組件內容非常全面,省去了后續的很多麻煩事情。

2 下載和使用 nssm.exe

nssm 軟件是一個非常小巧實用 Windows Service 管理工具,功能也很強大,
這里只使用最核心的功能,如果你對其它功能感興趣的話,可以詳細研究一下。
截止到目前 nssm 的最新版本是 2.24,下載地址為:http://www.nssm.cc/download

下載完成后,解壓縮會發現有分為 32 位和 64 位,
我的服務器是 64 位,因此我將 64 位的 nssm.exe 復制到服務器上即將要部署的文件夾 C:\CoreDemoService 文件夾下。
image

然后打開控制台,將 nssm.exe 拖動控制台窗口,后面跟上 install 參數,運行命令:

C:\CoreDemoService\nssm.exe install

彈出如下窗口,然后錄入相關的信息:

image

Application Path:
這個路徑是固定的,在 SDK 或相關 Runtime 安裝后,就會有 dotnet.exe 這個文件,選擇這個文件的絕對路徑即可。

Startup directory:
這個是服務所在的文件夾,因為我要安裝服務的所有文件都復制到了 C:\CoreDemoService 中,因此我填寫這個文件夾。

Arguments:
運行時的參數,這個選擇你程序發布時的 dll 文件即可,一般該文件的名稱與 exe 的名稱相同。

Service name:
服務的名字,這個名字會顯示在 Windows 服務中,你自己可以隨便命名。

以上參數填寫好后,點擊 Install service 即可。安裝成功后,到打開 服務 管理器,啟動服務即可。

image

3 瀏覽 Windows Service 部署的網站驗證部署效果

查看配置文件 appsettings.json ,我們配置的啟動端口為 9090。
(你也可以修改為其它端口,修改完成后,需要重新啟動服務即可)

我的服務器 ip 地址是:192.168.174.128

在我本機,打開瀏覽器,直接訪問 http://192.168.174.128:9090 即可,如下所示:

image

我之前本機的 hosts 文件中,添加了 www.testweb.com 指向服務器 ip 192.168.174.128,
因此我也可以通過域名加端口的方式訪問:

image

如果想要使用 80 端口訪問網站的話,只需要在服務器上安裝並配置 nginx 進行轉發即可,留在下面進行 Linux 部署時進行演示。

4 在進程中查看和識別服務

我們肯定會遇到這樣的場景:你使用 .NET Core 開發好的網站或者服務,部署成 Windows Service 后,使用 任務管理器 只能看到 .NET Host ,鼠標右鍵菜單選擇屬性查看具體信息,只能看到其路徑是 C:\Program Files\dotnet ,尤其是當服務器部署了好多 .NET Core 的 Windows Service 時,你就很難快速辨別每個 .NET Host 對應的是哪個服務。當你發現某些 .NET Core 的服務 CPU 占用很高或者內存占用很大,由於無法快速識別具體的服務,就很耽誤事情。

image

為了解決以上問題,我推薦一個工具軟件 Process Explorer ,下載地址為:

https://docs.microsoft.com/en-us/sysinternals/downloads/process-explorer

下載完成后解壓縮,我的服務器是 64 位的操作系統,因此我復制 procexp64.exe 到服務器上運行:

image

Process Explorer 跟任務管理器一樣,運行后也能查看每個進程的 CPU、內存、進程號等信息。

你可以選擇具體的每個 nssm.exe 下面的 dotnet.exe,通過右鍵菜單 properties ,彈出屬性框。
從里面的 Command line 和 Current directory 就可以快速辨別出是哪個服務,非常方便。

5 卸載 nssm 部署的 .NET Core 服務

如果想卸載服務:

1 先在服務管理器中,停止服務,這一步很重要。
如果不停止服務就卸載的話,雖然提示卸載成功,但是服務管理列表中還存在該服務,無法啟動,無法操作。
對於強迫症患者來說,是一種精神折磨。

2 找到被卸載服務所在的文件夾,打開控制台窗口,
將文件夾下的 nssm.exe 拖動到控制台窗口,后面跟上 remove 參數,運行命令:

C:\CoreDemoService\nssm.exe remove

在彈出的窗口中,輸入服務的名字,點擊 Remove service 即可刪除服務。

image

四、在 Linux 上部署

這里我們使用服務器操作系統 CentOS7 來進行演示,
使用 Xshell 進行命令行輸入,使用 xftp 進行本機和服務器之間文件的傳輸和操作。
(強烈建議使用 xftp 進行 Linux 上文件的傳輸和編輯操作,比通過命令行操作要方便很多)

我安裝的 CentOS7 服務器的 ip 地址為:192.168.8.143

1 首先使用 xftp 將發布的網站復制一份到 Linux 服務器上

使用 xftp 以 SFTP 的方式登錄 CentOS7 系統。(注意這里選擇的是 SFTP)

image

在 xftp 軟件界面中,左邊是你自己電腦本機的目錄和文件操作界面,右邊是遠程服務器的目錄和文件操作界面。

使用 xftp 通過右鍵菜單 “新建文件夾” 在 CentOS7 服務器的根目錄下創建一個文件夾 webapp,
將之前發布的網站文件復制到該文件夾下。(文件夾中 web.config 和 exe 文件都不是必須文件,可以刪除掉)

image

2 下載安裝 .NET SDK 或 ASP.NET Core 運行時

在 CentOS7 上安裝 .NET5 SDK 的官方文檔地址為:

https://docs.microsoft.com/zh-cn/dotnet/core/install/linux-centos

我在安裝 CentOS7 時,沒有創建其它賬號,我只能使用 root 賬號登錄,因此運行任何命令不需要在命令前加上 sodu,
如果你以普通用戶的身份登錄的話,則運行下面的安裝命令,則需要在前面加上 sudo,具體安裝步驟如下:

1 安裝 .NET 之前,請運行以下命令,將 Microsoft 包簽名密鑰添加到受信任密鑰列表,並添加 Microsoft 包存儲庫。

rpm -Uvh https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm

2 安裝 .NET SDK 或 ASP.NET Core 運行時(兩者只需要安裝其中任何一個即可

# 安裝 sdk
yum install dotnet-sdk-5.0

# 安裝運行時
yum install aspnetcore-runtime-5.0

3 安裝完成后,運行 dotnet --version 命令,如果能夠查看到版本號,則表明安裝成功


3 部署 .NET Core 網站

在 Linux 上部署 .NET Core 網站的官方文檔地址為:

https://docs.microsoft.com/zh-cn/aspnet/core/host-and-deploy/linux-nginx?view=aspnetcore-5.0

具體部署步驟為:
1 使用 xftp 找到 /etc/systemd/system 這個文件夾,通過鼠標右鍵 "新建文件" 創建一個服務的安裝配置文件,假設名稱為 CoreWebDemo.service

2 鼠標選擇 CoreWebDemo.service 這個文件,鼠標右鍵菜單 “用記事本編輯”。
(如果你電腦上安裝了 NotePad++ 或其它比較好用的文本編輯軟件的話,使用鼠標右鍵菜單 “打開”,在彈出的框中尋找和選擇相應的文本編輯軟件即可)

3 在文件中錄入以下內容即可,可以從官網上復制,然后進行修改並保存。

[Unit]
# 這個是服務的描述信息,可以隨便錄入
Description=我開發的 .NET5 網站 Demo

[Service]
# 這個網站或服務所在的文件夾,之前我們復制到了 /webapp 這個目錄
WorkingDirectory=/webapp
# 這個運行網站或服務的命令,建議都使用絕對路徑
# 其中前面的 /usr/bin/dotnet 是運行網站或服務所需要的命令
# 后面的 /webapp/CoreWebDemo.dll 是命令行參數,這個是程序的 dll 文件
ExecStart=/usr/bin/dotnet /webapp/CoreWebDemo.dll
# 服務崩潰時,是否重啟服務
Restart=always
# 如果服務奔潰,10 秒后重啟服務
RestartSec=10
KillSignal=SIGINT
# 系統日志的標識,可以隨便錄入,建議跟網站或服務的名字相同,這樣比較好識別
SyslogIdentifier=CoreWebDemo
# 以服務器上的哪個賬號運行服務,這里使用root賬號
User=root
# 設置環境變量,這里設置運行為生產環境
Environment=ASPNETCORE_ENVIRONMENT=Production
# 服務運行時是否打印臨時信息
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false

[Install]
# 服務運行在 linux 上的哪個 level,這里選擇多用戶命令行,也就是第 3 級別
WantedBy=multi-user.target

4 安裝和運行服務

服務的名字就是文件的名字
上面創建的文件名是 CoreWebDemo.service ,因此服務的名字就是 CoreWebDemo.service,
在使用 xshell 運行命令安裝和運行服務時,后綴名 .service 可以進行省略,運行以下命令即可:
特別注意,在 Linux 下文件名是區分大小寫的,因此服務名也區分大小寫

# 將服務設置為開機自動運行
systemctl enable CoreWebDemo
# 啟動服務
systemctl start CoreWebDemo
# 查看服務運行狀態
systemctl status CoreWebDemo

# 下面列出 停止服務 和 重啟服務 操作命令
systemctl stop CoreWebDemo
systemctl restart CoreWebDemo

image

4 使用瀏覽器訪問驗證

我們在網站部署成功后,有可能並不能訪問,還需要將網站的端口開通防火牆(不建議關閉防火牆)。

查看配置文件 appsettings.json ,我們配置的啟動端口為 9090。
(你也可以修改為其它端口,修改完成后,需要重新啟動服務即可)

因此使用以下命令將 9090 端口開通防火牆,然后 重新加載防火牆,以便防火牆配置生效

# 在防火牆中開通 9090 端口
firewall-cmd --zone=public --add-port=9090/tcp --permanent
# 重啟加載防火牆配置
firewall-cmd --reload

# 下面列出防火牆的其它操作命令

# 刪除防火牆之前開放的某個端口
firewall-cmd --zone=public --remove-port=9090/tcp --permanent
# 查看具體某個端口的開放狀態
firewall-cmd --query-port=80/tcp
# 查看已經開放了哪些端口
firewall-cmd --list-port
# 啟動防火牆
systemctl start firewalld
# 關閉防火牆
systemctl stop firewalld.service
# 開機自動運行防火牆
systemctl enable firewalld.service
# 禁用firewall(開機不會自動運行防火牆)
systemctl disable firewalld.service
# 查看防火牆狀態
systemctl status firewalld

我的 CentOS 服務器的 ip 地址是 192.168.8.143 ,網站啟動的端口是 9090,
我的電腦跟服務器在同一個 ip 網段,因此只需要訪問 http://192.168.8.143:9090 即可訪問網站,如下圖所示:

image

5 使用 nginx 轉發請求,通過 80 端口訪問網站

安裝 nginx 軟件,官網文檔地址是:http://nginx.org/en/linux_packages.html#RHEL-CentOS

安裝步驟如下:

1 運行命令 yum install yum-utils 安裝必備的工具包

2 使用 xftp 在 /etc/yum.repos.d 目錄下,創建 nginx.repo 文件,並從官網上復制以下內容,編輯並保存:

[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

3 然后使用 xshell 運行命令 yum install nginx 安裝最新版的 nginx 即可

4 安裝完成后,運行命令 nginx -v 查看 nginx 的版本,如果能夠查看到,則表示 nginx 安裝成功。

然后運行以下命令,確保 nginx 開機自動運行,以及重啟 nginx 服務

# 設置開機自動運行 nginx 服務
systemctl enable nginx

# 重啟啟動 nginx 服務,只需要重啟一次即可,后續不需要再重啟了
# 安裝好后,一般最好重啟一次 nginx 服務
# 否則后面修改了 nginx 的配置文件后,執行 nginx -s reload 重啟加載 nginx 配置時,可能會命令執行失敗
systemctl restart nginx

5 使用 xftp 訪問 /etc/nginx 目錄,可以看到 nginx.conf 這個主配置文件。打開主配置文件,在文件最后可以看到這樣一行:
include /etc/nginx/conf.d/*.conf;

說明 nginx.conf 會自動加載 /etc/nginx/conf.d 目錄下面所有后綴為 .conf 的配置文件。(在生產環境中,nginx.conf 這個主配置文件修改好后,后續就基本不會再動,絕大部分情況下都會去在 /etc/nginx/conf.d 目錄下,添加或修改具體的網站的配置文件)

我進入 /etc/nginx/conf.d 目錄下,創建一個配置文件 CoreWebDemo.conf 文件,從微軟官網上復制以下內容並修改保存:

server {
    listen        80;
    # 要綁定的域名
    server_name   www.testweb.com;
    
    # nginx 默認情況下,一次最大只允許上傳 1M 的文件
    # 你可以通過這個配置項進行修改,本示例修改為 10M
    client_max_body_size  10m;
    client_body_buffer_size 1m;
    
    location / {
    	# 將請求轉發到網站服務的端口
        proxy_pass         http://127.0.0.1:9090;
        proxy_http_version 1.1;
        proxy_set_header   Upgrade $http_upgrade;
        proxy_set_header   Connection keep-alive;
        proxy_set_header   Host $host;
        proxy_cache_bypass $http_upgrade;
        # 轉發客戶瀏覽器的 ip 地址
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
    }
}

6 使用 xshell 運行以下命令,使 nginx 重新加載配置:
# 重新加載 nginx 配置
nginx -s reload

# 如果上面的命令報錯,可以運行以下命令重啟 nginx
systemctl restart nginx
# 重啟 nginx 后,以后再運行 nginx -s reload 就沒問題了。
# 生產環境中,建議新增或修改了配置節后,使用 nginx -s reload

7 將防火牆開通 80 端口,並重新加載防火牆的配置,以便防火牆規則生效:
# 防火牆開通 80 端口
firewall-cmd --zone=public --add-port=80/tcp --permanent
# 重新加載防火牆配置
firewall-cmd --reload

8 在測試訪問網站的電腦上的 hosts 文件中,添加或修改域名指向

由於我們在 nginx 中給網站綁定的域名是 www.testweb.com,我的 Linux 服務器的 ip 地址為 192.168.8.143。
因此我在自己電腦 windows 系統的 hosts 文件中,添加域名指向記錄:
(如果之前已經添加過,則修改一下 www.testweb.com 指向的 ip 地址)

# hosts 文件存放在 C:\Windows\System32\drivers\etc 這個目錄下
192.168.8.143  www.testweb.com

9 檢查 Linux 服務器的 SeLinux 是否正在啟用,如果啟用的話,修改配置文件,徹底關閉它(這一步很重要)

SeLinux 是 Linux 系統的安全策略,在國內的服務器一般很少使用。相對於 Linux 使用的便利性而言,SeLinux 確實會在使用過程中帶來很多麻煩,因此安裝好 CentOS 系統后,首先要做的事情就是關閉它。
如果你不關閉它的話,在使用 CentOS 系統安裝軟件使用的過程中,經常會遇到一些莫名其妙的問題。有的時候查看日志也未必能夠發現是 SeLinux 搞得鬼。

比如我們上面的 nginx 、防火牆、hosts 文件的域名指向 都已經配置好了,但是在自己的電腦上進行訪問測試,報 502 Bad GateWay 錯誤,無法訪問,查看 nginx 日志可能會發現是 SeLinux 啟用導致的。

SeLinux 的配置文件在 /etc/selinux 目錄下,配置文件的名稱是 config,打開它進行編輯,將 SELINUX 后面的值修改為 disabled

image

然后使用 xshell 運行命令 init 6 重新啟動 Linux 服務器。(SeLinux 配置修改,必須重啟才能生效)

10 以上操作都完成后,接下來見證奇跡的時候到了

在我自己的電腦上,打開瀏覽器,訪問 www.testweb.com 如下圖所示,成功訪問網站,(#^.^#)

image

此時你可以將防火牆的 9090 端口關閉,這樣就只能通過 80 端口的域名訪問網站了。

firewall-cmd --zone=public --remove-port=9090/tcp --permanent




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM