Go語言在Linux中後台運行的問題?
如何在Linux系統上運行使用./test 關閉遠程的終端的時候後台也會被關閉? 這個問題如何解決?
我們這邊用法:
nohup ./bin/game_server 1&> game_server.out 2&> game_server.err
nohup這個命令可以把程序放後台運行,順便通過1&>和2&>把標準輸出和標準錯誤重定向到文件,這樣程序崩潰時才會有記錄可查,這兩者和程序的日誌最好是分開,混在一起沒辦法判斷輕重緩急。
進程啟動時候記錄下自己的pid:
if pid := syscall.Getpid(); pid != 1 {
ioutil.WriteFile("game_server.pid", []byte(strconv.Itoa(pid)), 0777)
defer os.Remove("game_server.pid")
}
同時監聽系統發來的kill信號,在收到kill信號時做些收尾工作:
signal.Notify(sigTERM, syscall.SIGTERM)
這樣就可以用kill命令關閉服務進程了:
kill `cat game_server.pid`
有一個Service庫專門處理後台運行的地址:http://github.com/kardianos/service,我自己也對這個包進行了簡單的封裝,你也可以才能考一下.utils/system_service.go at master · coffeehc/utils · GitHub
看你要運行的是個長時間的deamon,還是一個臨時跑起來的程序,希望退出時不被關掉。
如果是deamon需求,建議納入upstart,systemd,supervisor這種進程管理程序的管理,可以自動重啟,還會有日誌輪轉這些功能。這幾個裡面supervisor相對功能最弱,但是配置最簡單;upstart是ubuntu拿來代替initv的程序,配置簡單,功能強大;systemd是redhat用來代替initv的程序,配置略難看,但是功能最多,甚至會做進程資源隔離,保證程序退出時不會出現沒被關閉的進程。
如果只是臨時程序不希望停止,我一般用screen,缺點是console只能保存一段。使用nohup加重定向也可以。為什麼不用screen?
使用 supervisor 託管, 記得要把代碼中所有輸出到 stdout,stderr 的列印語句注意掉
要長久運行的,請遵循系統規範:upstart / sysvinit,搭配其它輔助監控系統。
寫 PID 之類的事情,本來就應該是啟動器做的,不應該放在 Go binary 部分。
如果不是 daemon,只是等不及程序跑完想回頭看進度,用 tmux 是王道。supervisor託管,新語言都有這玩意,後台運行,監視進程,沒有了會自動拉起
啊哈哈,前些時再golang群也有人問過這個問題,正好也碰到了,後來一位大牛告訴我最簡單的辦法你寫個bash,然後再裡面./test 然後運行腳本,這樣關掉terminal,進程也不會退出貌似完全不需要那麼複雜的方法,雖說挺好用,但是一直沒理解原理啊。。。
這算不上什麼go專有問題嘛。當你的terminal退出的時候, 系統會發送一個HUP 信號到所有屬於這個terminal的子進程。
推薦閱讀:
※如何看待Phoenix用40核128G內存的機器只能同時保持僅僅200萬WebSocket連接?
※GoLang不需要Rakefile/Makefile,是如何實現交叉編譯的?如在X86上生成MIPS的可執行。
※作為一名WEB工程師從長遠的角度來講 哪幾種語言 更值得深入學習?
※如何理解 Golang 中「不要通過共享內存來通信,而應該通過通信來共享內存」?
※為什麼 Go 語言如此不受待見?
TAG:Go語言 |