一、概要
整個流程如下:
1、部署. NET Core相關的運行環境,基本就是運行時或者SDK
2、將發布的項目文件傳到Linux系統
3、通過命令將項目啟動並指定端口號
4、添加Supervisor進程守護監控
二、環境介紹
本文用到的操作系統和軟件版本如下:
Linux:centos8.3
VS開發工具:Visual Studio 2019 Professional
SDK 版本:.NET Core 5.0
三、部署過程
1、安裝.NET Core環境
客戶端通過Xshell打開Centos8.3終端,然后切換成root權限,不然后邊的很多操作沒有權限。
安裝.NET SDK,.NET SDK 使你可以通過 .NET 開發應用。 如果安裝 .NET SDK,則無需安裝相應的運行時。
sudo dnf install dotnet-sdk-5.0

#查看Dotnet 版本信息
dotnet --version
#查看Dotnet 版本信息 dotnet --info

2、發布.NET Core項目

注意這里使用的是框架依賴部署模式,因為之前我們已經安裝了.NET Core環境,這里就不使用獨立部署模式了。下面介紹下什么是依賴部署,什么是獨立部署模式?
框架依賴部署
依賴框架的部署 (FDD) 是指依賴目標系統上 .NET Core環境。 由於已存在 .NET Core環境,因此應用在 .NET Core 安裝程序間也是可移植的。
優點:部署包很小。 部署中只需要應用及其依賴項,而無需包含 .NET Core環境。
缺點:
①、僅當主機系統上已安裝你設為目標的 .NET Core 版本或更高版本時,應用才能運行。
②、如果不了解將來版本,.NET Core 運行時和庫可能發生更改。 在極少數情況下,這可能會更改應用的行為。
獨立部署
獨立部署 (SCD) 是指不依賴目標系統上存在的共享組件。 所有組件(包括 .NET Core 庫和 .NET Core 運行時)都包含在應用程序中,並且獨立於其他 .NET Core 應用程序。
優點:
①、可以對與應用一起部署的 .NET Core 版本具有單獨的控制權
②、目標系統可以運行你的 .NET Core 應用,因為你提供的是應用將在其上運行的 .NET Core 版本
缺點:
①、由於 .NET Core環境 包含在部署包中,因此必須提前選擇為其生成部署包的目標平台
②、部署包相對較大,因為需要將 .NET Core環境 和應用及其第三方依賴項包括在內。
③、向系統部署大量獨立的 .NET Core 應用可能會使用大量磁盤空間,因為每個應用都會復制 .NET Core 文件
3、將發布的項目上傳到Linux系統
我是用的是XShell6工具上傳的,主要就是使用XShell上傳壓縮包,然后在Linux系統上解壓,具體操作可以參考博文:Linux遠程連接及上傳文件和Linux-Centos下安裝工具用來解壓壓縮 。我們先來看一下發布項目的文件夾列表:

可以看到安裝包是rar的,CentOS本身不自帶rar環境,因此對於rar文件無法直接解壓,需要先配置rar環境,可以參考解壓:Linux-Centos下安裝工具用來解壓壓縮

4、啟動和停止.NET Core項目
首先進入目錄/publish,就是存放項目的目錄

利用dotnet命令啟動項目
#啟動站點,自定義端口號,運行環境
dotnet HyWebSocketServer.dll

訪問啟動的站點
#訪問啟動的站點
http://ip:9000
#停止站點 Ctrl+c
瀏覽器打開如下:

四、Supervisor守護進程
1、守護進程是什么?
在linux或者unix操作系統中,守護進程(Daemon)是一種運行在后台的特殊進程,它獨立於控制終端並且周期性的執行某種任務或等待處理某些發生的事件。由於在linux中,每個系統與用戶進行交流的界面稱為終端,每一個從此終端開始運行的進程都會依附於這個終端,這個終端被稱為這些進程的控制終端,當控制終端被關閉的時候,相應的進程都會自動關閉。但是守護進程卻能突破這種限制,它脫離於終端並且在后台運行,並且它脫離終端的目的是為了避免進程在運行的過程中的信息在任何終端中顯示並且進程也不會被任何終端所產生的終端信息所打斷。它從被執行的時候開始運轉,直到整個系統關閉才退出。在 Linux 上有很多可以管理進程的工具,我們使用 Supervisor 來做這個事情。
原因有兩點:
①、它是微軟官方文檔推薦的,降低學習成本。
②、它並不一定是最好的,但一定是文檔最全的。
2、Supervisor概述
Supervisor是一個客戶端/服務器系統,用 Python 開發的一套通用的進程管理程序,能將一個普通的命令行進程變為后台 daemon,並監控進程狀態,異常退出時能自動重啟。supervisor 還能很友好的管理程序在命令行上輸出的日志,可以將日志重定向到自定義的日志文件中,還能按文件大小對日志進行分割。supervisor主要包含以下四個部分:
- supervisord:supervisord是supervisor的服務端,負責管理我們配置的子進程,包括重啟崩潰或異常退出的子進程,同時也響應來自客戶端的請求。
-
supervisorctl:supervisord的客戶端命令行。我們可以通過supervisorctl獲得由主進程控制的子進程的狀態,停止和啟動子進程,並獲得主進程的運行列表。
-
Web Server:和supervisorctl功能差不多,是通過web界面查看和控制進程狀態。
-
XML-RPC Interface:服務於web UI的同一個HTTP服務器提供一個XML-RPC接口,可以用來詢問和控制管理程序及其運行的程序。
3、安裝Supervisor
#執行epel-release
sudo yum -y install epel-release #安裝Supervisor sudo yum -y install supervisor #通過配置文件來啟動supervisor sudo supervisord -c /etc/supervisord.conf #啟動supervisorctl sudo supervisorctl -c /etc/supervisord.conf #查看supervisor 版本 version

4、創建Supervisor配置文件
進入supervisord.d目錄
cd /etc/supervisord.d
新建NetCore進程配置文件
sudo touch WsServerNetCore.ini

查看和編輯WsServerNetCore.ini配置文件
sudo vim WsServerNetCore.ini
進入文件后,按“i”或者“a”進入插入模式,插入下面的配置信息
#配置程序名稱
[program:HyWebSocketServer]
#運行程序的命令
command=dotnet HyWebSocketServer.dll
#命令執行的目錄
directory=~/publish
#進程環境變量
environment=ASPNETCORE_ENVIRONMENT=Production
#進程執行的用戶身份
user=root
#進程停止信號,可以為TERM, HUP, INT, QUIT, KILL, USR1, or USR2等信號默認為TERM >。當用設定的信號去干掉進程,退出碼會被認為是expected,非必須設置
stopsignal=INT
#如果是true的話,子進程將在supervisord啟動后被自動啟動,默認就是true,非必須設置
autostart=true
#這個是設置子進程掛掉后自動重啟的情況,有三個選項,false,unexpected和true。如果>為false的時候,無論什么情況下,都不會被重新啟動,如果為unexpected,只有當進程的>退出碼不在下面的exitcodes里面定義的退出碼的時候,才會被自動重啟。當為true的時候>>,只要子進程掛掉,將會被無條件的重啟
autorestart=true
#這個選項是子進程啟動多少秒之后,此時狀態如果是running,則我們認為啟動成功了,默認值為1,非必須設置
startsecs=1
#錯誤日志文件
stderr_logfile=~/HyWebSocketServer/hyWebSocketServer.err.log
#輸出日志文件
stdout_logfile=~/HyWebSocketServer/hyWebSocketServer.out.log
按ESC,輸入命令:wq保存配置文件
5、啟動supervisor
#啟動方式1:通過supervisor服務端使用配置文件啟動
sudo supervisord -c /etc/supervisord.conf
#啟動方式2:通過客戶端命令行啟動 #先啟動supervisorctl sudo supervisorctl -c /etc/supervisord.conf #重新加載配置文件 reload #查看運行的狀態 status
####################出現了以下錯誤:
錯誤一:
Error: Another program is already listening on a port that one of our HTTP servers is configured to use. Shut this program down first before starting supervisord.
解決方法:
ps aux | grep supervisord kill - 9 進程ID
錯誤二:
Unlinking stale socket /var/run/supervisor/supervisor.sock
解決方法:
unlink /var/run/supervisor/supervisor.sock
########################

測試下站點是否運行正常
#查看相關進行 ps -aux | grep "HyWebSocketServer.dll" #訪問啟動的站點 https://ip:9000

注意:這里有個問題就是,當Linux系統關機后,Supervisor可能不會自己開啟,導致需要手動執行sudo supervisord -c /etc/supervisord.conf 命令之后,Dotnet進程才會自動啟動
6、Supervisor開機自啟動
#進入system目錄 cd /usr/lib/systemd/system #編輯supervisord.service文件 sudo vim supervisord.service
supervisord.service文件內容如下
[Unit]
Description=Process Monitoring and Control Daemon After=rc-local.service nss-user-lookup.target [Service] Type=forking ExecStart=/usr/bin/supervisord -c /etc/supervisord.conf ExecStop=/usr/bin/supervisorctl shutdown ExecReload=/usr/bin/supervisorctl reload KillMode=process Restart=on-failure RestartSec=42 [Install] WantedBy=multi-user.target
編輯好后保存退出,然后執行命令,查看是否啟動成功
#啟動服務 systemctl enable supervisord #驗證一下是否為開機啟動 systemctl is-enabled supervisord

7、守護進程的效果
直接干掉Dotnet進程,看看會不會自動啟動
#查看dotnet進程
ps -aux|grep dotnet #強制殺死dotnet進程 kill -9 PID #再次查看dotnet進程 ps -aux|grep dotnet

重啟Linux,然后直接訪問站點
8、supervisorctl 常用命令
supervisorctl 是 supervisord的命令行客戶端工具
# 啟動所有進程 supervisorctl start all # 重啟所有進程 supervisorctl restart all # 停止所有進程 supervisorctl stop all #PS:要操作某個服務,把all換成服務名即可
#重新啟動配置中的所有程序
supervisorctl reload
#查看服務狀態 supervisorctl status
9、防火牆配置
在配置urls的時候,不能使用http://localhost:9000類似這樣的,否則即使把防火牆都關閉了,外網或者局域網都不能訪問站點,當然了,不能因為外網或者局域網訪問,我們就把防火牆關閉了,這樣做對系統是很不安全的。防火牆的作用是防止不希望的、未授權的通信進出被保護的網絡,迫使單位強化自己的網絡安全政策。一般的防火牆都可以達到以下目的:
①、可以限制他人進入內部網絡,過濾掉不安全服務和非法用戶;
②、防止入侵者接近你的防御設施;
③、限定用戶訪問特殊站點。
④、為監視Internet安全提供方便。
先查看防火牆的狀態,然后開放之前.NET Core項目所用到的9000端口,最后查看防火牆所開放的端口
#查看防火牆狀態 sudo firewall-cmd --state #開放9000端口 sudo firewall-cmd --zone=public --add-port=9000/tcp --permanent #重啟防火牆 sudo firewall-cmd --reload #查看防火牆開放的端口 sudo firewall-cmd --list-ports
注意:--permanent,這里是永久的意思,如果沒有使用這個命令,重啟Linux系統后,防火牆策略將會消失
10、防火牆常用命令
#關閉防火牆
systemctl stop firewalld.service
#開啟防火牆
systemctl start firewalld.service
#關閉開機自啟動
systemctl disable firewalld.service
#開啟開機自啟動
systemctl enable firewalld.service
#查看某個端口是否開啟
firewall-cmd --query-port=80/tcp #查看防火牆狀態 firewall-cmd --state #查看防火牆開放的端口 firewall-cmd --list-ports #永久開放某個TCP端口 firewall-cmd --zone=public --add-port=80/tcp --permanent #永久關閉某個TCP端口 firewall-cmd --zone=public --remove-port=80/tcp --permanent #永久開放某個UDP端口 firewall-cmd --zone=public --add-port=80/udp --permanent #永久關閉某個UDP端口 firewall-cmd --zone=public --remove-port=80/udp --permanent #批量添加區間端口 firewall-cmd --zone=public --add-port=8081-8082/tcp --permanent firewall-cmd --zone=public --add-port=8081-8082/udp --permanent
