標籤:

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`

最初試過自己用系統調用實現daemon進程,但是發現和pprof模塊有衝突,一pprof就死鎖,不知道是姿勢不對還是早期Go的BUG,反正那時候起就換成nohup形式了,簡單好用。


有一個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語言 |