Linux進(jìn)程管理:supervisor和nohup原理及使用

原理

守護(hù)進(jìn)程(daemon)

守護(hù)進(jìn)程是一類在后臺(tái)運(yùn)行的特殊進(jìn)程,用于執(zhí)行特定的系統(tǒng)任務(wù)。他獨(dú)立于控制終端并且周期性的執(zhí)行某種任務(wù)或等待處理某些發(fā)生的事件。Linux系統(tǒng)的大多數(shù)服務(wù)器就是通過(guò)守護(hù)進(jìn)程實(shí)現(xiàn)的。
常見(jiàn)的守護(hù)進(jìn)程包括:

  • 系統(tǒng)日志進(jìn)程syslogd
  • Web服務(wù)器httpd
  • 郵件服務(wù)器sendmail
  • 數(shù)據(jù)庫(kù)服務(wù)器mysqld等

守護(hù)進(jìn)程一般在系統(tǒng)啟動(dòng)時(shí)開(kāi)始運(yùn)行,除非強(qiáng)行終止,否則會(huì)持續(xù)運(yùn)行知道系統(tǒng)關(guān)機(jī),通常以超級(jí)用戶(root)權(quán)限運(yùn)行。

前臺(tái)任務(wù)與后臺(tái)任務(wù)

假如有個(gè)簡(jiǎn)單的go的web服務(wù)器程序,使用如下方式啟動(dòng),稱為前臺(tái)任務(wù)。獨(dú)占了命令窗口,只有運(yùn)行完了或手動(dòng)終止(Ctrl+C),才能執(zhí)行其他命令。


如果以如下方式,在命令結(jié)尾加上符號(hào)&,啟動(dòng)的進(jìn)程就會(huì)稱為后臺(tái)任務(wù)。


后臺(tái)任務(wù)又如下特點(diǎn):

  • 繼承當(dāng)前session的標(biāo)準(zhǔn)輸出(stdout)和標(biāo)準(zhǔn)錯(cuò)誤(stderr),因此如上圖所示,后臺(tái)任務(wù)的所有輸出仍會(huì)同步的在命令行顯示
  • 不再繼承當(dāng)前session的標(biāo)準(zhǔn)輸入(stdin),無(wú)法向這個(gè)任務(wù)輸入指令,如果它試圖讀取標(biāo)準(zhǔn)輸入,就會(huì)暫停執(zhí)行(halt)

SIGHUP信號(hào)

變?yōu)楹笈_(tái)任務(wù)并不代表進(jìn)程成為了守護(hù)進(jìn)程,因?yàn)楫?dāng)session關(guān)閉后,后臺(tái)任務(wù)就會(huì)終止。Linux系統(tǒng)終端session退出流程如下:

  1. 用戶準(zhǔn)備退出session
  2. 系統(tǒng)向改session發(fā)送SIGHUP信號(hào)
  3. session將SIGHUP信號(hào)發(fā)送給所有子進(jìn)程
  4. 子進(jìn)程收到SIGHUP信號(hào)后會(huì)自動(dòng)退出

nohup

nohup 是后臺(tái)作業(yè)的意思, nohup運(yùn)行的進(jìn)程將會(huì)忽略終端信號(hào)運(yùn)行。即后臺(tái)運(yùn)行一個(gè)命令。nohup COMMAND & 用nohup運(yùn)行命令可以使命令永久的執(zhí)行下去,和用戶終端沒(méi)有關(guān)系,例如我們斷開(kāi)SSH連接都不會(huì)影響它的運(yùn)行。

使用nohup命令的方式可以啟動(dòng)一個(gè)守護(hù)進(jìn)程,如下圖所示:


nohup命令對(duì)進(jìn)程做了如下操作:

  • 忽略SIGHUP信號(hào),因此當(dāng)session關(guān)閉進(jìn)程就不會(huì)退出
  • 關(guān)閉標(biāo)準(zhǔn)輸入,該進(jìn)程不再接收任何輸入,即使運(yùn)行在前臺(tái)
  • 重定向標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤到文件nohup.out(默認(rèn)情況,可以指定輸出的文件)

nohup不會(huì)自動(dòng)把進(jìn)程變?yōu)楹笈_(tái)任務(wù),所以必須加上&。

supervisor

supervisor是用Python開(kāi)發(fā)的一套通用的進(jìn)程管理程序,能將一個(gè)普通的命令行進(jìn)程變?yōu)楹笈_(tái)daemon,并監(jiān)控進(jìn)程狀態(tài),異常退出時(shí)能自動(dòng)重啟。
supervisor管理進(jìn)程是通過(guò)fork/exec的方式把被管理的進(jìn)程當(dāng)做子進(jìn)程來(lái)啟動(dòng),用戶只需要在配置文件中將要管理的進(jìn)程進(jìn)行配置。

結(jié)構(gòu)

supervisor主要由Supervisord、Supervisorctl、Web server和XML-RPC interface組成:

  • supervisord:主進(jìn)程,負(fù)責(zé)管理進(jìn)程的server,它會(huì)根據(jù)配置文件創(chuàng)建指定數(shù)量的應(yīng)用程序的子進(jìn)程,管理子進(jìn)程的整個(gè)生命周期,對(duì)crash的進(jìn)程重啟,對(duì)進(jìn)程變化發(fā)送事件通知等。同時(shí)通過(guò)內(nèi)置web server和XML-RPC Interface可以輕松實(shí)現(xiàn)進(jìn)程管理。
  • supervisorctl:管理client,用戶通過(guò)命令行發(fā)送消息給supervisord,可以查看進(jìn)程狀態(tài),加載配置文件,啟停進(jìn)程,查看進(jìn)程標(biāo)準(zhǔn)輸出和錯(cuò)誤輸出,遠(yuǎn)程操作等。
  • Web server:superviosr提供了web server功能,可通過(guò)web控制進(jìn)程。
  • XML-RPC interface: XML-RPC接口,提供XML-RPC服務(wù)來(lái)對(duì)子進(jìn)程進(jìn)行管理和監(jiān)控。

macOS環(huán)境安裝使用

安裝并啟動(dòng)

$ brew install supervisor
$ brew services start supervisor

創(chuàng)建配置目錄和配置文件

默認(rèn)的配置文件路徑為/usr/local/etc/supervisord.conf,查看該文件可以看到如下內(nèi)容:

$ tail -n2 /usr/local/etc/supervisord.conf
[include]
files = /usr/local/etc/supervisor.d/*.ini

可以看到include了/usr/local/etc/supervisor.d/目錄下的.ini文件,因此我們需要?jiǎng)?chuàng)建改目錄,然后對(duì)要管理的進(jìn)程或進(jìn)程組創(chuàng)建對(duì)應(yīng)的.ini格式的配置文件

$ mkdir -pv /usr/local/etc/supervisor.d
$ vim /usr/local/etc/supervisor.d/myserver.ini

編輯配置文件內(nèi)容如下:

[program:server]
process_name=%(program_name)s_%(process_num)02d
command=/usr/local/go/bin/go run /Users/harryzhang/go/src/server/server.go # 要執(zhí)行的命令
autostart=true # 系統(tǒng)開(kāi)機(jī)自動(dòng)啟動(dòng)
autorestart=true # 進(jìn)程終止自動(dòng)重啟
user=harryzhang # 用戶
numprocs=1 # 啟動(dòng)進(jìn)程數(shù)
redirect_stderr=true # 是否將標(biāo)準(zhǔn)錯(cuò)誤重定向到標(biāo)準(zhǔn)輸出
stdout_logfile=/Users/harryzhang/go/src/server/server.log # 指定標(biāo)準(zhǔn)輸出保存的文件路徑

重啟supervisor

編輯好配置文件后重啟supervisor就可以生效,可以使用supervisorctl命令查看和管理進(jìn)程狀態(tài)。

$ brew services restart supervisor
Stopping `supervisor`... (might take a while)
==> Successfully stopped `supervisor` (label: homebrew.mxcl.supervisor)
==> Successfully started `supervisor` (label: homebrew.mxcl.supervisor)

$ supervisorctl status
server:server_00                 RUNNING   pid 41382, uptime 0:00:04

如果指定的命令執(zhí)行沒(méi)有異常,會(huì)看到進(jìn)程已處于運(yùn)行狀態(tài),如果沒(méi)有處于運(yùn)行狀態(tài),可以查看日志文件,可能為命令執(zhí)行出錯(cuò)直接退出了。

參考

【1】Linux 守護(hù)進(jìn)程的啟動(dòng)方法
【2】進(jìn)程管理工具supervisor 和 nohup

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容