.NET Core部署到linux(CentOS)最全解決方案,進階篇(Supervisor+Nginx)

.NET快速開發框架發表於2021-01-21

.NET Core部署到linux(CentOS)最全解決方案,常規篇一文,我們詳細講解了傳統的.NET Core部署到Linux伺服器的方法,學到了Linux在虛擬機器下的安裝、Xshell,Xftp的使用方法、git在linux下的互動使用以及.net core在linux下的釋出與執行全過程。本文講講解通過使用Supervisor+Nginx的組合來實現.net core的高效部署。

1、Supervisor

1.1、Supervisor介紹

官網:http://supervisord.org,原始碼位置:https://github.com/Supervisor/supervisor

Supervisor是用Python開發的一套通用的程式管理程式,能將一個普通的命令列程式變為後臺daemon,並監控程式狀態,異常退出時能自動重啟。

它是通過fork/exec的方式把這些被管理的程式當作supervisor的子程式來啟動,這樣只要在supervisor的配置檔案中,把要管理的程式的可執行檔案的路徑寫進去即可。也實現當子程式掛掉的時候,父程式可以準確獲取子程式掛掉的資訊的,可以選擇是否自己啟動和報警。supervisor還提供了一個功能,可以為supervisord或者每個子程式,設定一個非root的user,這個user就可以管理它對應的程式。

1.2、為什麼要用Supervisor

在linux或者unix作業系統中,守護程式(Daemon)是一種執行在後臺的特殊程式,它獨立於控制終端並且週期性的執行某種任務或等待處理某些發生的事件。由於在linux中,每個系統與使用者進行交流的介面稱為終端,每一個從此終端開始執行的程式都會依附於這個終端,這個終端被稱為這些程式的控制終端,當控制終端被關閉的時候,相應的程式都會自動關閉。但是守護程式卻能突破這種限制,它脫離於終端並且在後臺執行,並且它脫離終端的目的是為了避免程式在執行的過程中的資訊在任何終端中顯示並且程式也不會被任何終端所產生的終端資訊所打斷。它從被執行的時候開始運轉,直到整個系統關閉才退出。

此處的建立守護程式,是指釋出在Linux上 asp.net core 程式的dotnet xxx.dll命令的宿主程式建立一個守護程式。在 Linux 上有很多可以管理程式的工具,我們使用 Supervisor 來做這個事情。

原因有兩點:

①、它是微軟官方文件推薦的,降低學習成本。
②、它並不一定是最好的,但一定是文件最全的。

1.3、Supervisor4大元件

  • supervisord

主程式,負責管理程式的server,它會根據配置檔案建立指定數量的應用程式的子程式,管理子程式的整個生命週期,對crash的程式重啟,對程式變化傳送事件通知等。同時內建web server和XML-RPC Interface,輕鬆實現程式管理。。該服務的配置檔案在/etc/supervisor/supervisord.conf。

  • supervisorctl

客戶端的命令列工具,提供一個類似shell的操作介面,通過它你可以連線到不同的supervisord程式上來管理它們各自的子程式,命令通過UNIX socket或者TCP來和服務通訊。使用者通過命令列傳送訊息給supervisord,可以檢視程式狀態,載入配置檔案,啟停程式,檢視程式標準輸出和錯誤輸出,遠端操作等。服務端也可以要求客戶端提供身份驗證之後才能進行操作。

  • Web Server

superviosr提供了web server功能,可通過web控制程式(需要設定[inethttpserver]配置項)

  • XML-R- #supervisor

一個Linux/Unix系統上的程式監控工具
一個Python開發的通用的程式管理程式
可以管理和監控Linux上面的程式
能將一個普通的命令列程式變為後臺daemon,並監控程式狀態,異常退出時能自動重啟
不過同daemontools一樣,它不能監控daemon程式

1.4、安裝Supervisor

相應安裝建議以管理員方式登入系統,非管理員請以sudo命令安裝。

Linux sudo命令以系統管理者的身份執行指令,也就是說,經由 sudo 所執行的指令就好像是 root 親自執行。

1、安裝EPEL源的命令如下:

sudo yum -y install epel-release

安裝EPEL源

2、執行如下命令安裝supervisor:

sudo yum -y install supervisor

3、設定開機啟動:

systemctl enable supervisord

4、啟動supervisord

systemctl start supervisord

5、檢視supervisord狀態

systemctl status supervisord

1.5、Supervisor配置及使用

通過vi命令或者xftp修改配置檔案開啟web介面訪問,如下圖所示,分別取消inet_http_server等四個配置的註釋:

vi /etc/supervisord.conf

執行如下命令,重新載入配置檔案:

supervisorctl reload

然後在瀏覽器開啟http://你的ip:9001,輸入上面我們設定的使用者名稱:user1,密碼:123456後,如圖所示:


看到上圖這個介面,就表示supervisor安裝完成了。

切換到/etc/supervisord.d目錄,在此目錄建立名稱為:core50test.ini的ini檔案,內容如下:

#表示程式名稱,用於在supervisor中顯示,無特殊意義。
[program:core50test] 
# 輸入執行命令,這裡表示執行的是dotnet Core50Test.dll
command=/bin/bash -c "dotnet Core50Test.dll"
# 應用程式根目錄 
directory=/root/app_data/core50test/publish
# 是否自動啟動,當 supervisor 載入該配置檔案的時候立即啟動它 
autostart=true
# 是否自動重啟, 程式異常退出後自動重啟
autorestart=true
# 該配置檔案輸出單個日誌檔案的大小,預設50M
logfile_maxbytes=50MB
# 日誌備份個數 
logfile_backups=10
# 記錄日誌級別 
loglevel=info
# 指定標準輸出日誌檔案 
stdout_logfile=/root/app_data/data/logs/core50test/core50test.out.log
# 環境變數
environment=ASPNETCORE_ENVIRONMENT=Production
# 啟動服務的使用者
user=root
# 把stderr重定向到stdout,預設 false
redirect_stderr=true

上述程式碼包含了註釋資訊,參考精減版配置如下:

[program:core50test]
command=/bin/bash -c "dotnet Core50Test.dll"
directory=/root/app_data/core50test/publish
autostart=true
autorestart=true
logfile_maxbytes=50MB
logfile_backups=10
loglevel=info
stdout_logfile=/root/app_data/data/logs/core50test/core50test.out.log
environment=ASPNETCORE_ENVIRONMENT=Production
user=root
redirect_stderr=true

注意:stdout_logfile指向的資料夾一定要先建立,否則無法啟動,上述配置檔案中的內容需要根據使用者實際情況修改,如我當前登入的使用者是:yonghu,你們是其他的就做相應的修改即可。

然後執行如下命令來重新載入配置:

supervisorctl reload

命令執行成功後, 重新整理瀏覽器,可以看到如下介面:

supervisor正在執行的應用

當介面顯示running時,則表示我們我們剛剛配置的.net core應用執行起來了。

如下圖所示。

我們可以方便的通過supervisor提供的web管理介面對我們的應用進行啟動與停止,檢視日誌等操作,非常的方便,絲般潤滑般的爽呀。

Supervisor啟動與停止應用

檢視日誌:

1.6、Supervisor常用命令

### 檢視supervisorctl支援的命令
# supervisorctl help    
default commands (type help <topic>):
=====================================
add    exit      open  reload  restart   start   tail   
avail  fg        pid   remove  shutdown  status  update 
clear  maintail  quit  reread  signal    stop    version

### 檢視當前執行的程式列表
# supervisorctl status

  • update 更新新的配置到supervisord(不會重啟原來已執行的程式)

  • reload,載入所有配置檔案,並按新的配置啟動、管理所有程式(會重啟原來已執行的程式)

  • start xxx: 啟動某個程式

  • restart xxx: 重啟某個程式

  • stop xxx: 停止某一個程式(xxx),xxx為[program:theprogramname]裡配置的值

  • stop groupworker: 重啟所有屬於名為groupworker這個分組的程式(start,restart同理)

  • stop all,停止全部程式,注:start、restart、stop都不會載入最新的配置文

  • reread,當一個服務由自動啟動修改為手動啟動時執行一下就ok

最常用的幾個命令為:

#啟動所有
supervisorctl start all

# 重啟所有
supervisorctl restart all

# 停止所有
supervisorctl stop all

#PS:要操作某個服務,把all換成服務名即可
#檢視服務狀態
supervisorctl status

2、使用Nginx

在前面文章中,我們已經可以非常方便的對web應用進行部署與管理了,但還存在一個問題,我們的應用程式預設是繫結的5000埠,如果要指定80埠或者配置域名該怎麼處理呢?下面就該nginx登場了。

2.1、Nginx介紹

Nginx是一款輕量級的Web 伺服器/反向代理伺服器及電子郵件(IMAP/POP3)代理伺服器,在BSD-like 協議下發行。其特點是佔有記憶體少,併發能力強,事實上nginx的併發能力在同型別的網頁伺服器中表現較好,中國大陸使用nginx網站使用者有:百度、京東、新浪、網易、騰訊、淘寶等。

2.2、Nginx安裝

安裝方式參考:http://nginx.org/en/linux_packages.html#RHEL-CentOS

安裝先決條件:

 sudo yum install -y yum-utils

設定yum儲存庫,先建立一下內容的檔案:/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

預設情況下,使用穩定 nginx 包的儲存庫。如果要使用主線 nginx 包,請執行以下命令:

 yum-config-manager --enable nginx-mainline

執行如下命令安裝nginx:

 sudo yum install -y nginx

設定開機啟動:

systemctl enable nginx

啟動nginx:

 systemctl start nginx

此時,就可以在瀏覽器通過ip訪問了:http://你的ip,介面如下:

2.3、Nginx部署

nginx安裝完成後,切換到/etc/nginx/conf.d目錄,修改default.conf檔案內容,如下所示:

server {
    listen       80;
    server_name  localhost;
    location / {
        proxy_pass http://0.0.0.0:5000;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

儲存後,執行如下命令,重新載入配置:

nginx -s reload

然後再次訪問http://你的ip,一切正常的話應該可以看到如下的介面,表示我們的.NET Core程式已經完美執行在linux系統了。

如果部署後遇到型別下面這樣的錯誤

出現這樣的問題,有可能的是因為SeLinux的限制,執行如下命令之後,再重新整理頁面:

setenforce 0     

selinux(security enhanced linux)安全增強型linux系統,它是一個linux核心模組,也是linux的一個安全子系統。

selinux的主要作用就是最大限度地減小系統中服務程式可訪問的資源(最小許可權原則)

如果設定後還是不能解決,可以檢視nginx的日誌了,預設的日誌路徑為:/var/log/nginx

通過setenforce 0命令,只是臨時實效,重啟後會失效。

可以通過修改/etc/selinux/config 檔案,將SELINUX=enforcing改為SELINUX=disabled,然後重啟,即可永久生效。

通過近兩篇文章的介紹,我們需要更新應用,只需要將程式碼提交到git倉庫,然後在伺服器中執行git pull和dotnet publish即可。

如果熟悉shell的話,可以通過編寫shell命令一鍵執行應用程式的更新,程式碼示例:

# !/bin/bash
cd /root/app_data/source/core50test
git pull
dotnet publish -o /root/app_data/core50test/publish
supervisorctl restart core50test

將上述的程式碼儲存為sh檔案,上傳到伺服器,並設定許可權。如下圖所示:

程式碼提交到git倉庫後,執行如下命令:

./build.sh

執行結果如下圖所示:

更新後重新執行,已經更新。

這兒可能有的小夥伴會遇到一個小小的坑要注意,shell指令碼寫得沒有問題,執行會報類似這樣的錯誤

$'\r':command not found

出現這種問題是因為windows下的檔案換行用的是\r\n,而linux系統用的是\n,如果在win下的文件上傳到linux,就有可能出現這樣的問題,只需用vi開啟shell指令碼檔案,然後使用命令:set ff=unix,儲存檔案即可。

supervisor一個作為守護執行緒,用於維護應用程式的生命週期的,nginx則是作為反向代理使用,配置shell可以做到高效部署,非常的方便。


一路走來數個年頭,感謝RDIFramework.NET框架的支持者與使用者,大家可以通過下面的地址瞭解詳情。

RDIFramework.NET官方網站:http://www.rdiframework.net/

RDIFramework.NET官方部落格:http://blog.rdiframework.net/

特別說明,框架相關的技術文章請以官方網站為準,歡迎大家收藏!

RDIFramework.NET框架由海南國思軟體科技有限公司專業團隊長期打造、一直在更新、一直在升級,請放心使用!

歡迎關注RDIFramework.NET框架官方微信公眾號(微訊號:guosisoft),及時瞭解最新動態。

使用微信掃描二維碼立即關注

微訊號:guosisoft

相關文章