目前来看,貌似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
其他操作都可以直接查看源码