目前來看,貌似golang的daemon解決方案都是讓程序本身運行之后在程序內部再次啟動自己,脫離終端, 好像也沒有其他更好的方法.
一般情況下,一個 golang 服務除了讓他 daemon 運行,還需要停止,重啟操作, 對這些操作,我做了統一處理,
daemon 提供了一組接口 daemon.Worker , 自己的程序需要做的就是先實現這個接口, 這個接口包含以下幾個方法
PidSavePath() string 返回一個pid存放路徑
Name() string 返回服務的名字, 這個名字將作為終端啟動時的參數
Start() 啟動服務的操作, 將在終端執行傳入 start 時執行
Stop() error 終止服務前的操作,將在終端執行傳入 stop 時執行
Restart() error 重啟服務前的操作,將在終端執行傳入 restart 時執行
實現以上接口之后, 在 main 調用以下操作
proc := daemon.NewProcess(new(YourImpl)).SetPipeline(nil, out, err)
SetPipeline 最多支持三個參數, 分別對應 標准輸入 標准輸出 錯誤輸出, 這個方法不是必須的
proc返回對象還可以監聽其他系統信號量,完成你自定義的操作, 當然這在Windows下無法實現
如果使用 daemon.GetCommand().AddWorker(proc) 添加,假如你編譯的程序名字叫做 app, 那么你會擁有以下命令
app {name} start
app {name} stop
app {name} restart
如果使用 daemon.Register(proc) 添加, 那么你會擁有以下命令
app start
app stop
app restart
最后代碼 daemon.Run(); 讓所有操作都運行起來
一個具體的例子就像 HTTP 服務器,這里有一個完整的例子 https://github.com/medivh-jay/daemon/blob/master/examples/main.go
終端的命令控制由 github.com/spf13/cobra 提供, 你的程序可能除了以上基本命令參數操作,可能還有一些自定義參數, 那么你可以實現下邊這個接口在你上邊的實現中
type Command interface {
SetCommand(cmd *cobra.Command)
}
這個接口如果被實現,將在程序啟動前執行, 你可以在這一步將 cmd 保存到你的實現中, 在 Start 方法中調用他獲得你自定義的參數, 這個示例也在這里邊 https://github.com/medivh-jay/daemon/blob/master/examples/main.go
其他操作都可以直接查看源碼