引言
在Linux上部署.Net Core App最好的方式是在Linux機器上使用Kestrel 服務在端口5000上支撐web應用; 然后設置Nginx作為反向代理服務器,將輸入請求轉發給Kestrel服務器, 這個模式稱為 邊緣代理服務器(edge-origin proxy)。
使用這種部署模型有如下優勢:
-
可擴展性: 反向代理服務器和Web服務器可以設置在一台或者不同的機器上,為伸縮部署提供可能, 可按需部署多個Web服務器,Nginx反向代理服務器本身可充當優秀的負載均衡器。
-
數據安全性:edge-origin 模式隱藏了 Web服務器進程的細節,對外只暴露80端口,對外暴露的只有Nginx 反向代理服務器,減少了網絡攻擊的可能性。
-
高性能:反向代理服務器可以為后端服務器配置 內容緩存,減少對后端服務器的請求,這是個很重要的性能提升,避免DDOS攻擊和暴力惡意攻擊。
-
多功能性:本文雖然是在講述Linux-only 部署, 這種模式允許你高效、透明地混合使用Linux和Windows服務器,以上Web服務器也可以是 IIS-Powered的Web服務器。
准備部署
首先明確dotnet程序是一個獨立進程, 原本可不依賴反向代理服務器運行; 必備知識點
第二明確Nginx反向代理服務器的作用, 這里我們需要為.NetCore 程序添加必要的中間件
// Invoke the UseForwardedHeaders middleware and configure it to forward the X-Forwarded-For and X-Forwarded-Proto headers. // NOTE: This must be put BEFORE calling UseAuthentication or similar authentication scheme middlewares. // ref.: https://www.ryadel.com/en/asp-net-core-2-publish-deploy-web-application-linux-centos-tutorial-guide-nginx app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto });
第三明確dotnet程序需要在Linux系統中以守護進程的方式運行,可使用 supervisor、systemd等方式。
1. 安裝環境
sudo rpm -Uvh https://packages.microsoft.com/config/rhel/7/packages-microsoft-prod.rpm
-- rpm是一種軟件包管理方式,這里的微軟軟件包倉庫以rpm包的形式提供,包含倉庫配置和供發行版認證軟件包的公鑰,你可以理解為添加了一個nuget包倉庫 sudo yum update sudo yum install aspnetcore-runtime-2.2
-- yum基於rpm包管理,能夠從指定服務器自動下載rpm包並且安裝,可自動處理依賴關系,並一次安裝所有依賴軟件包。
2. dotnet程序發布、測試
- 使用VS項目右鍵發布到指定目錄
- 使用zip方式打包
- 使用scp、SFTP工具上傳到Linux服務器, 一般情況下拷貝到var目錄
scp D:\production\eqidproxyServer.zip root@10.201.80.126:/var/www --以下命令將zip包拷貝到 /var/www目錄下
- 在CentOS服務器上解壓
unzip -d eqidproxyServer eqidproxyServer.zip
- 執行dotnet EqidProxyServer.dll
3. 使用systemd將dotnet進程設置成Linux守護進程
完成以上步驟,dotnet程序並不能在后台作為服務運行,Nginx雖然能作為反向代理服務器轉發請求到dotnet進程, 但是並不具備管理dotnet進程的能力。
下面使用 systemd來將dotnet進程設定為系統服務。
systemd是一個Linux的系統服務管理器,其作用是提供系統服務依賴管理 、實現系統初始化時服務的並行啟動。
[Unit] Description=EqidProxyServer deploy on centos [Service] WorkingDirectory=/var/www/eqidproxyserver/eqidproxyServer ExecStart=/usr/bin/dotnet /var/www/eqidproxyserver/eqidproxyServer/EqidProxyServer.dll Restart=always # Restart service after 10 seconds if the dotnet service crashes: RestartSec=10 TimeoutStopSec=90 KillSignal=SIGINT SyslogIdentifier=dotnet-example User=root Environment=ASPNETCORE_ENVIRONMENT=Production Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false [Install] WantedBy=multi-user.target
黃色背景行是需要你注意配置的,這里我們使用root來執行dll, 一般情況下需要創建一個web賬戶,並給予項目文件夾owner權限。
下面在root用戶組下創建www-data用戶,並給予owner權限。
sudo useradd -m -g root www-data sudo chown www-data var/www/eqidproxyserver
注意:Linux 是大小寫敏感的文件系統,設定ASPNETCORE_ENVIRONMENT=Production 會在配置文件中搜索如下配置文件: appsettings.Production.json, 故配置和文件名需要留意匹配。
sudo systemctl enable kestrel-eqidproxyserver.service // 啟用服務 sudo systemctl start kestrel-eqidproxyserver.service // 指定服務名啟動 sudo systemctl status kestrel-eqidproxyserver.service // 驗證服務狀態
以下是驗證服務狀態的輸出:
● kestrel-eqidproxyserver.service - EqidProxyServer deploy on centos Loaded: loaded (/etc/systemd/system/kestrel-eqidproxyserver.service; enabled; vendor preset: disabled) Active: active (running) since Thu 2019-02-28 18:04:20 CST; 3min 2s ago Main PID: 52859 (dotnet) Memory: 46.3M CGroup: /system.slice/kestrel-eqidproxyserver.service └─52859 /usr/bin/dotnet /var/www/eqidproxyserver/eqidproxyServer/EqidProxyServer.dll Feb 28 18:06:18 gs-server-5809 dotnet-eqidproxyserver[52859]: info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2] Feb 28 18:06:18 gs-server-5809 dotnet-eqidproxyserver[52859]: Request finished in 136.6715ms 200 Feb 28 18:06:23 gs-server-5809 dotnet-eqidproxyserver[52859]: info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1] Feb 28 18:06:23 gs-server-5809 dotnet-eqidproxyserver[52859]: Request starting HTTP/1.1 GET http://127.0.0.1/ Feb 28 18:06:23 gs-server-5809 dotnet-eqidproxyserver[52859]: info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2] Feb 28 18:06:23 gs-server-5809 dotnet-eqidproxyserver[52859]: Request finished in 3.5599ms 200 Feb 28 18:06:32 gs-server-5809 dotnet-eqidproxyserver[52859]: info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1] Feb 28 18:06:32 gs-server-5809 dotnet-eqidproxyserver[52859]: Request starting HTTP/1.1 GET http://10.201.80.126/ Feb 28 18:06:32 gs-server-5809 dotnet-eqidproxyserver[52859]: info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2] Feb 28 18:06:32 gs-server-5809 dotnet-eqidproxyserver[52859]: Request finished in 1.3498ms 200
4. 搭配Nginx部署web程序
- sudo yum install nginx 【首次安裝需要顯式啟動: sudo service nginx start】
CentOS安裝的nginx並沒有作為守護進程運行,執行sudo systemctl enable nginx 啟用nginx守護進程: https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-centos-7Ubuntu 中使用 apt-get 安裝的nginx, 安裝器會創建systemd init script,也就是說nginx會隨着系統啟動作為守護程序運行。
- 在終端使用curl localhost 測試nginx
- 修改/etc/nginx/nginx.conf 文件: sudo vi /etc/nginx/nginx.conf
- 配置nginx在80端口將請求轉發到Kestrel服務器(localhost:5000)
server { listen 80; server_name default_website; root /usr/share/nginx/html; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { proxy_pass http://localhost:5000; 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; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } error_page 404 /404.html; location = /40x.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } }
一旦nginx配置完成,可以使用sudo nginx -t 測試配置文件的語法;
如果配置文件合法,就可以重啟nginx: sudo nginx -s reload
完成以上步驟之后,現在已經可以從127.0.0.1、127.0.0.1:5000、 服務器IP訪問web程序。
5.查看進程日志
使用systemd方式管理進程,所有事件和進程都會記錄到某個集中日志,該集中日志包含所有被systend管理的服務和進程的日志。
這個日志功能相當於windows服務器中的事件查看器。
查看剛才建立的服務日志, 可使用下面的命令:
sudo journalctl -fu kestrel-eqidproxysever.service
時間過濾:
sudo journalctl -fu kestrel-eqidproxysever.service --since "2018-11-18" --until "2019-03-28 04:00"
部分內容參考: https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/linux-nginx?viw=aspnetcore-2.2
rpm/yum區別: https://zhuanlan.zhihu.com/p/27724520
Linux進程管理:https://linux.cn/article-3801-1.html
感謝您的認真閱讀,如有問題請大膽斧正;覺得有用,請下方或加關注。
本文歡迎轉載,但請保留此段聲明,且在文章頁面明顯位置注明本文的作者及原文鏈接。