Golang:二进制更新时如何自动重启进程?

fan*_*ard 0 deployment go

我在本地构建了 golang 应用程序,然后scp到服务器。我需要停止该过程并手动重新启动。有没有办法在二进制文件更新时自动重启进程?

Pab*_*oni 6

虽然这通常最好使用 daemontools 或类似的东西在进程外实现,但在某些情况下,您希望/需要在程序内部完成。

根据程序特性(例如连接或可能打开的文件等),在程序中执行此操作可能会很棘手。

话虽如此,这里有一个在大多数情况下都可以工作的实现:

package main

import (
    "log"
    "os"
    "syscall"
    "time"

    "github.com/fsnotify/fsnotify"
    "github.com/kardianos/osext"
)

func setupWatcher() (chan struct{}, error) {
    file, err := osext.Executable()
    if err != nil {
        return nil, err
    }
    log.Printf("watching %q\n", file)
    w, err := fsnotify.NewWatcher()
    if err != nil {
        return nil, err
    }
    done := make(chan struct{})
    go func() {
        for {
            select {
            case e := <-w.Events:
                log.Printf("watcher received: %+v", e)
                err := syscall.Exec(file, os.Args, os.Environ())
                if err != nil {
                    log.Fatal(err)
                }
            case err := <-w.Errors:
                log.Printf("watcher error: %+v", err)
            case <-done:
                log.Print("watcher shutting down")
                return
            }
        }
    }()
    err = w.Add(file)
    if err != nil {
        return nil, err
    }
    return done, nil
}

func main() {
    log.Print("program starting")
    watcher, err := setupWatcher()
    if err != nil {
        // do something sensible
        log.Fatal(err)
    }
    // continue with app startup
    time.Sleep(100 * time.Minute) // just for testing
    // eventually you may need to end the watcher
    close(watcher) // this way you can
}
Run Code Online (Sandbox Code Playgroud)

然后你做

% go build main.go     
% ./main
2016/12/29 14:15:06 program starting
2016/12/29 14:15:06 watching "/home/plalloni/tmp/v/main"
Run Code Online (Sandbox Code Playgroud)

这是在您(在其他终端中)运行(在其他终端中)一些连续的“go build main.go”(“更新”正在运行的二进制文件)后产生的输出。

2016/12/29 14:15:32 watcher received: "/home/plalloni/tmp/v/main": CHMOD
2016/12/29 14:15:32 program starting
2016/12/29 14:15:32 watching "/home/plalloni/tmp/v/main"
2016/12/29 14:15:38 watcher received: "/home/plalloni/tmp/v/main": CHMOD
2016/12/29 14:15:38 program starting
2016/12/29 14:15:38 watching "/home/plalloni/tmp/v/main"
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你。