【Golang】程序通过服务的形式常驻后台

0x00

此教程只在Linux和Windows上试验过,Mac可自行实验

一般使用命令带&实现后台运行,或使用守护进程来实现后台运行。
其实golang自己也可以实现以服务的形式常驻后台。

需要的库

这里使用库:github.com/kardianos/service

其中golang.org/x/...的库国内很难下载,将golang.org/x/替换为github.com/golang/进行下载,最后将github.com->golang文件目录替换为golang.org->x文件目录即可。

接口定义

这个库有两个接口定义:

type Service interface {
    // Run should be called shortly after the program entry point.
    // After Interface.Stop has finished running, Run will stop blocking.
    // After Run stops blocking, the program must exit shortly after.
    Run() error

    // Start signals to the OS service manager the given service should start.
    Start() error

    // Stop signals to the OS service manager the given service should stop.
    Stop() error

    // Restart signals to the OS service manager the given service should stop then start.
    Restart() error

    // Install setups up the given service in the OS service manager. This may require
    // greater rights. Will return an error if it is already installed.
    Install() error

    // Uninstall removes the given service from the OS service manager. This may require
    // greater rights. Will return an error if the service is not present.
    Uninstall() error

    // Opens and returns a system logger. If the user program is running
    // interactively rather then as a service, the returned logger will write to
    // os.Stderr. If errs is non-nil errors will be sent on errs as well as
    // returned from Logger's functions.
    Logger(errs chan<- error) (Logger, error)

    // SystemLogger opens and returns a system logger. If errs is non-nil errors
    // will be sent on errs as well as returned from Logger's functions.
    SystemLogger(errs chan<- error) (Logger, error)

    // String displays the name of the service. The display name if present,
    // otherwise the name.
    String() string
}
type Interface interface {
    // Start provides a place to initiate the service. The service doesn't not
    // signal a completed start until after this function returns, so the
    // Start function must not take more then a few seconds at most.
    Start(s Service) error

    // Stop provides a place to clean up program execution before it is terminated.
    // It should not take more then a few seconds to execute.
    // Stop should not call os.Exit directly in the function.
    Stop(s Service) error
}

这里只需实现startstop接口就行

0x01 简单实例

type program struct{}
func (p *program) Start(s service.Service) error {
    log.Println("开始服务")
    go p.run()
    return nil
}
func (p *program) Stop(s service.Service) error {
    log.Println("停止服务")
    return nil
}
func (p *program) run() {
    // 这里放置程序要执行的代码……
}

func main(){
//服务初始化
    //服务的配置信息
    cfg := &service.Config{
        Name:        "simple",
        DisplayName: "a simple service",
        Description: "This is an example Go service.",
    }
    // Interface 接口
    prg := &program{}
    // 构建服务对象
    s, err := service.New(prg, cfg)
    if err != nil {
        log.Fatal(err)
    }
    // logger 用于记录系统日志
    logger, err := s.Logger(nil)
    if err != nil {
        log.Fatal(err)
    }
    if len(os.Args) == 2 { //如果有命令则执行
        err = service.Control(s, os.Args[1])
        if err != nil {
            log.Fatal(err)
        }
    } else { //否则说明是方法启动了
        err = s.Run()
        if err != nil {
            logger.Error(err)
        }
    }
    if err != nil {
        logger.Error(err)
    }
}
Last modification:November 7th, 2019 at 06:01 pm
如果觉得我的文章对你有用,请随意赞赏

Leave a Comment