windows和linux平臺下后臺運行程序的實現(xiàn)(守護(hù)進(jìn)程、后臺任務(wù))

一、 前言

  • WindowsLinux平臺下有時候需要后臺啟動, 脫離界面(拋去黑色cmd和脫離終端)運行程序并常駐內(nèi)存;同時能夠具備一定的日志記錄和異常自啟動等特點。
  • 對于后臺啟動和守護(hù)進(jìn)程概念上不做過多區(qū)分;當(dāng)然我們可以通過使用Web服務(wù)器托管或者直接運行啟動;但這些與后臺運行相違背
  • 由于筆者是golang開發(fā)的web項目,并且已經(jīng)打包成可執(zhí)行文件,就簡單了解下目前已知的偏后端后臺啟動的幾種方式(前端的推薦一個pm2挺不錯的)。當(dāng)然通過docker部署是個不錯的策略,但是與今天討論的話題是有很大區(qū)別的。

二、 Windows環(huán)境程序后臺運行

對于windows環(huán)境很少會用來作為服務(wù)器,由于系統(tǒng)的定位和其一定的封閉性使得在這快能夠選擇的方式不多。

1. 對于c#程序winform和.net

對于這類可以直接通過隱藏窗體任務(wù)欄或直接創(chuàng)建windows服務(wù)程序(推薦),這塊內(nèi)容請移步至微軟官方文檔 創(chuàng)建windows服務(wù)了解

2. 對于不是通過打包執(zhí)行

這里很多是通過安裝使用第三方庫用代碼控制,如golang的github.com/kardianos/service

3. 對于其他程序打包后生成的可執(zhí)行文件

例如 golang 或者 python等程序打包后生成的.exe可執(zhí)行文件,如果想實現(xiàn)脫離命令行、脫離終端運行,則需要將 可執(zhí)行文件注冊成windows服務(wù)。
(備注): 有了解到網(wǎng)上說使用: sc命令、start /b xxx.exe命令.vbs文件 、 .bat、c/c++懵圈代碼修改注冊表等。個人觀點不推薦,原因有二:簡便性和通用性。
這里有兩個程序,但是推薦最后一個b
a. 微軟Microsoft Windows Resource Kits工具集中提供的兩個小工具“instsrv.exe”和“srvany.exe” 但是要求手動修改注冊表,所以不太建議用:
先下載這兩個程序然后放在同一個目錄,例如都放在D盤,然后進(jìn)入到DOS命令行下面輸入如下命令注冊服務(wù):

 d:\instsrv.exe mySharedService d:\srvany.exe        //mySharedService是服務(wù)名
 // 這個命令是把srvany.exe這個程序注冊成了系統(tǒng)服務(wù) 

接下來需要修改注冊表
同時按住windows鍵r鍵 在彈出的運行框中輸入regedit ,然后回車。修改HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services 路徑下找到剛剛注冊的服務(wù)名mySharedService,右擊新建一個項,名稱為“Parameters”,單擊選中它然后在右側(cè)的窗口新建一個字符串值名稱為“Application”,將其值設(shè)置為要注冊的可執(zhí)行文件exe的路徑。同樣的方式也可以指定再建立一個AppDirectory指定程序運行的初始目錄;AppParameters 值為程序啟動所需要的參數(shù)等。
然后運行net start mySharedService即可啟動,停止刪除服務(wù),見net 命令
b. 通過使用nssm程序來實現(xiàn)可執(zhí)行程序的注冊服務(wù),簡單高效
首先,安裝官網(wǎng)安裝 nssm 解壓選里面的64位系統(tǒng)的執(zhí)行程序,將nssm.exe添加到系統(tǒng)環(huán)境變量(或者跟上面一樣放到d盤)
然后注冊服務(wù),通過如下命令(mgt_test_service為服務(wù)名)

nssm install  mgt_test_service

會出現(xiàn)窗口提示,通過配置如下

nssm配置圖.png

右邊的details可以配置服務(wù)的展示名稱和描述信息,以及啟動方式
nssm-details配置圖.png

點擊 install service即可注冊服務(wù);
服務(wù)管理主要有啟動、停止和重啟,其命令如下:
啟動服務(wù):nssm start mgt_test_service
停止服務(wù): nssm stop mgt_test_service
重啟服務(wù): nssm restart mgt_test_service
當(dāng)然,也可以使用系統(tǒng)自帶的服務(wù)管理器操作和使用系統(tǒng)的命令
如果需要修改參數(shù)可以使用: nssm edit mgt_test_service
如果刪除服務(wù)可以使用: nssm remove mgt_test_service
通過在運行窗口輸入 services.msc 可以找到mgt_test_service這個服務(wù)。

三、Linux環(huán)境程序后臺運行

其實Linux系統(tǒng)有自己的守護(hù)進(jìn)程管理工具 Systemd,直接和內(nèi)核的交互可以將服務(wù)變成系統(tǒng)服務(wù),性能也很強,本文不進(jìn)行介紹。這里推薦幾個常用的工具和命令并簡述他們之間的區(qū)別。
命令:nohupscreen
工具:supervisor

1. nohup命令

用法 nohup ./web_pack & (web_pack是打包后的可執(zhí)行文件, '&'可以將當(dāng)前進(jìn)程變成后臺任務(wù))

nohup的特點:

  • 該命令會阻止SIGHUP信號發(fā)到這個進(jìn)程
  • 關(guān)閉標(biāo)準(zhǔn)輸入,該進(jìn)程不再能夠接收任何輸入
  • 重定向標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯誤到文件nohup.out

2. screen命令

  • 首先安裝
# 安裝screen 多數(shù)linux系統(tǒng)已經(jīng)安裝了
apt-get install screen

操作流程如下:

  • 新建一個screen會話
# 新建一個session
screen
# 創(chuàng)建多個session, 需要指定name區(qū)分
screen -S name1
screen -S name2
# 查看已經(jīng)創(chuàng)建的session
screen -ls
  • 出現(xiàn)如下頁面,表示安裝成功,依據(jù)提示我們按一個空格鍵
    新建screen會話頁面.png
  • 接下我們執(zhí)行啟動項目的命令
# 進(jìn)入項目,啟動運行服務(wù)(web_pack是我打包后的可執(zhí)行文件,這里依據(jù)情況執(zhí)行自己項目的啟動命令)
./web_pack
web_pack啟動演示圖片.png

可以看到我的服務(wù)啟動并監(jiān)聽了8088端口,但是還沒有脫離終端,當(dāng)前仍處于上面創(chuàng)建的screen session。我們需要退出跳出這個screen,執(zhí)行如下命令。

  • 離開當(dāng)前的screen 會話
    按住 ctrl + Actrl + D,會跳出當(dāng)前創(chuàng)建的screen,可以看到下面的頁面
    跳出screen界面.png

    通過測試訪問本地8088端口得到返回數(shù)據(jù),確實服務(wù)已經(jīng)后臺啟動了。
    測試本地服務(wù).png

    關(guān)閉終端后并不影響后臺程序運行。
  • 刪除已經(jīng)創(chuàng)建的screen
    先進(jìn)入,如果只有一個可以直接 screen -r,多個可以通過screen -r name1;
    然后停掉服務(wù),關(guān)閉退出,按住 ctrl + Cctrl + D,即可關(guān)閉如下圖所示
    關(guān)閉session會話.png

screen的特點:

  • 可在當(dāng)前screen session 里新建另一個或多個 session;
  • 當(dāng)前 session是否關(guān)閉不影響創(chuàng)建的session;
  • 以后重新登錄,還可以再連上早先新建的 session;
  • 不具備服務(wù)托管特性,沒有出錯重啟或日志跟蹤等

3. supervisor進(jìn)程托管工具

supervisor是我用的較多的守護(hù)進(jìn)程管理工具,python開發(fā)的可將一個普通的命令行進(jìn)程變?yōu)楹笈_daemon,并監(jiān)控進(jìn)程狀態(tài),支持異常重啟和支持運行日志的記錄。
詳細(xì)文檔說明參考supervisor 官網(wǎng)

  • 安裝supervisor
# ubuntu系統(tǒng)通過apt安裝
apt-get install supervisor
# pip 安裝
pip install supervisor
  • 配置supervisor
    進(jìn)入到/etc/supervisor可以看到如下目錄內(nèi)容
    supervisor配置目錄結(jié)構(gòu).png

    supervisor的配置文件supervisord.conf
    需要管理的子進(jìn)程配置文件目錄/conf.d
    本人已添加的配置文件hexo_auto.conf
    這里貼一下網(wǎng)上的關(guān)于配置文件的說明,了解下即可,被管理的進(jìn)程配置見后。
[unix_http_server]
file=/tmp/supervisor.sock   ;UNIX socket 文件,supervisorctl 會使用
;chmod=0700                 ;socket文件的mode,默認(rèn)是0700
;chown=nobody:nogroup       ;socket文件的owner,格式:uid:gid
 
;[inet_http_server]         ;HTTP服務(wù)器,提供web管理界面
;port=127.0.0.1:9001        ;Web管理后臺運行的IP和端口,如果開放到公網(wǎng),需要注意安全性
;username=user              ;登錄管理后臺的用戶名
;password=123               ;登錄管理后臺的密碼
 
[supervisord]
logfile=/tmp/supervisord.log ;日志文件,默認(rèn)是 $CWD/supervisord.log
logfile_maxbytes=50MB        ;日志文件大小,超出會rotate,默認(rèn) 50MB,如果設(shè)成0,表示不限制大小
logfile_backups=10           ;日志文件保留備份數(shù)量默認(rèn)10,設(shè)為0表示不備份
loglevel=info                ;日志級別,默認(rèn)info,其它: debug,warn,trace
pidfile=/tmp/supervisord.pid ;pid 文件
nodaemon=false               ;是否在前臺啟動,默認(rèn)是false,即以 daemon 的方式啟動
minfds=1024                  ;可以打開的文件描述符的最小值,默認(rèn) 1024
minprocs=200                 ;可以打開的進(jìn)程數(shù)的最小值,默認(rèn) 200
 
[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ;通過UNIX socket連接supervisord,路徑與unix_http_server部分的file一致
;serverurl=http://127.0.0.1:9001 ; 通過HTTP的方式連接supervisord
 
; [program:xx]是被管理的進(jìn)程配置參數(shù),xx是進(jìn)程的名稱
[program:xx]
command=/opt/apache-tomcat-8.0.35/bin/catalina.sh run  ; 程序啟動命令
autostart=true       ; 在supervisord啟動的時候也自動啟動
startsecs=10         ; 啟動10秒后沒有異常退出,就表示進(jìn)程正常啟動了,默認(rèn)為1秒
autorestart=true     ; 程序退出后自動重啟,可選值:[unexpected,true,false],默認(rèn)為unexpected,表示進(jìn)程意外殺死后才重啟
startretries=3       ; 啟動失敗自動重試次數(shù),默認(rèn)是3
user=tomcat          ; 用哪個用戶啟動進(jìn)程,默認(rèn)是root
priority=999         ; 進(jìn)程啟動優(yōu)先級,默認(rèn)999,值小的優(yōu)先啟動
redirect_stderr=true ; 把stderr重定向到stdout,默認(rèn)false
stdout_logfile_maxbytes=20MB  ; stdout 日志文件大小,默認(rèn)50MB
stdout_logfile_backups = 20   ; stdout 日志文件備份數(shù),默認(rèn)是10
; stdout 日志文件,需要注意當(dāng)指定目錄不存在時無法正常啟動,所以需要手動創(chuàng)建目錄(supervisord 會自動創(chuàng)建日志文件)
stdout_logfile=/opt/apache-tomcat-8.0.35/logs/catalina.out
stopasgroup=false     ;默認(rèn)為false,進(jìn)程被殺死時,是否向這個進(jìn)程組發(fā)送stop信號,包括子進(jìn)程
killasgroup=false     ;默認(rèn)為false,向進(jìn)程組發(fā)送kill信號,包括子進(jìn)程
 
;包含其它配置文件
[include]
files = relative/directory/*.ini    ;可以指定一個或多個以.ini結(jié)束的配置文件

上面的配置文件中"[program:xx]"部分也說明了被管理進(jìn)程的配置參數(shù),這里放一下上面我的hexo_auto.conf的簡單配置

[program:hexo-blog]
command=/usr/local/node/bin/hexo server
directory=/root/hexo/my-hexo-blog
autostart=true
startsecs=10
autorestart=true
startretries=3
# 執(zhí)行的用戶
user=root
# 值小的優(yōu)先啟動
priority=999
# 把stderr重定向到stdout,默認(rèn)false
redirect_stderr=true
stdout_logfile_maxbytes=20MB
# 備份文件數(shù)目
stdout_logfile_backups = 20
# 日志文件
stdout_logfile=/root/hexo/my-hexo-blog.log
# 默認(rèn)為false,進(jìn)程被殺死時,是否向這個進(jìn)程組發(fā)送stop信號,包括子進(jìn)程
stopasgroup=false
# 默認(rèn)為false,向進(jìn)程組發(fā)送kill信號,包括子進(jìn)程
killasgroup=false

這個配置是用來在/root/hexo/my-hexo-blog路徑下啟動hexo服務(wù)的代碼,服務(wù)起名為hexo-blog

  • 運行supervisor并添加子進(jìn)程任務(wù)hexo-blog,最后啟動任務(wù)即可。
# 啟動服務(wù)
sudo service supervisor start
# 更新下配置
sudo supervisorctl update
# 啟動任務(wù)
sudo supervisorctl start hexo-blog

如果修改了子進(jìn)程任務(wù)的配置,則需要重新加載運行。參考下面命令:

常用的supervisor命令有:
supervisorctl status //查看所有進(jìn)程的狀態(tài)
supervisorctl stop hexo-blog //停止hexo-blog
supervisorctl start hexo-blog //啟動hexo-blog
supervisorctl restart //重啟hexo-blog
supervisorctl update //配置文件修改后使用該命令加載新的配置
supervisorctl reload //重新啟動配置中的所有程序

四、結(jié)語

由于調(diào)研、搭建環(huán)境、編寫文章時間倉促和能力有限,文章難免存在用詞不當(dāng)或知識錯誤,歡迎指正。如果有更好的后臺程序運行或者守護(hù)進(jìn)程的管理的見解,歡迎評論區(qū)討論交流。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,333評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,491評論 3 416
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,263評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,946評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,708評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,186評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,409評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,939評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,774評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,976評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,209評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,641評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,872評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,650評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 47,958評論 2 373