【问题标题】:Can i run a golang application as a background process? ( without nohup)我可以将 golang 应用程序作为后台进程运行吗? (没有 nohup)
【发布时间】:2020-06-25 06:34:34
【问题描述】:

是否可以在代码级别将 golang 应用程序作为后台进程运行,而不使用 nohup?

我在以下链接中找到了一个示例:- https://socketloop.com/tutorials/golang-daemonizing-a-simple-web-server-process-example

它可以工作,但感觉有点骇人听闻......有人知道我可以在不产生新进程的情况下做同样的事情吗?

谢谢

【问题讨论】:

  • 您不能 fork 一个 go(或任何其他多线程)进程。您需要使用现代的初始化系统或其他控制过程来为您处理。

标签: go


【解决方案1】:

有像 go-daemon 这样的包可以做到这一点,但是你的程序将很难在非 POSIX 系统上运行。

如果您面向多个平台,我建议您将应用程序编写为自行守护进程并将该任务留给任何系统服务管理器,如 systemd、daemontools、supervisord 或任何 Mac OS X 或 Windows 使用。

【讨论】:

    【解决方案2】:

    对于那些有兴趣的人。我使用github.com/kardianos/service 包解决了这个问题。它通过将应用程序安装为服务来工作,我可以从命令行启动或停止它而不会阻塞。经过测试,它可以在 Linux 和 Windows 上运行,这符合我的目的。

    我会喜欢这样的示例代码:-

    package main
    
    import (
        "flag"
        "fmt"
        "log"
        "net/http"
    
        "github.com/kardianos/service"
    )
    
    var logger service.Logger
        
    // Program structures.
    //  Define Start and Stop methods.
    type program struct {
        exit chan struct{}
    }
    
    func (p *program) Start(s service.Service) error {
        if service.Interactive() {
            logger.Info("Running in terminal.")
        } else {
            logger.Info("Running under service manager.")
        }
        p.exit = make(chan struct{})
    
        // Start should not block. Do the actual work async.
        go p.run()
        return nil
    }
    func (p *program) run() error {
        logger.Infof("I'm running %v.", service.Platform())
        http.HandleFunc("/", handler)
        log.Fatal(http.ListenAndServe(":8080", nil))
        return nil
    }
    func (p *program) Stop(s service.Service) error {
        // Any work in Stop should be quick, usually a few seconds at most.
        logger.Info("I'm Stopping!")
        close(p.exit)
        return nil
    }
    
    func handler(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
    }
    
    func main() {
        svcFlag := flag.String("service", "", "Control the system service.")
        flag.Parse()
    
        options := make(service.KeyValue)
        options["Restart"] = "on-success"
        options["SuccessExitStatus"] = "1 2 8 SIGKILL"
        svcConfig := &service.Config{
            Name:         "GoExample",
            DisplayName:  "Go Example",
            Description:  "This is a Go application.",
            Dependencies: []string{},
            // "Requires=network.target",
            // "After=network-online.target syslog.target"
            Option: options,
        }
    
        prg := &program{}
        s, err := service.New(prg, svcConfig)
        if err != nil {
            log.Fatal(err)
        }
        errs := make(chan error, 5)
        logger, err = s.Logger(errs)
        if err != nil {
            log.Fatal(err)
        }
    
        go func() {
            for {
                err := <-errs
                if err != nil {
                    log.Print(err)
                }
            }
        }()
    
        if len(*svcFlag) != 0 {
            err := service.Control(s, *svcFlag)
            if err != nil {
                log.Printf("Valid actions: %q\n", service.ControlAction)
                log.Fatal(err)
            }
    
            return
        }
    
        err = s.Run()
        if err != nil {
            logger.Error(err)
        }
    
    }
    

    【讨论】:

      【解决方案3】:

      您可以使用&amp;disown

      示例:

      path/to/program&amp; more info

      disownmore info

      之后,您可以关闭 ssh 或终端。

      要查看程序正在运行,您可以使用ps aux

      另见Difference between nohup, disown and &

      【讨论】:

      • 嗨,我想从代码中控制它。不看 nohup,& 和不承认。
      猜你喜欢
      • 2017-04-14
      • 1970-01-01
      • 2011-07-14
      • 1970-01-01
      • 2022-01-01
      • 2012-12-22
      • 1970-01-01
      • 2020-12-20
      • 1970-01-01
      相关资源
      最近更新 更多