diff --git a/content/_index.md b/content/_index.md index 252177a7..dc68fb4c 100644 --- a/content/_index.md +++ b/content/_index.md @@ -115,6 +115,7 @@ - [Golang 函数可选参数模式](go/function-optional-pattern.md) - [Golang 密钥对、数字签名和证书管理](go/go-cert-management.md) - [Golang 不同平台架构编译](go/go-cross-complie.md) +- [Golang 守护进程](go/go-daemon.md) - [Golang 生成证书](go/go-gen-cert.md) - [go:linkname 指令](go/go-linkname.md) - [Golang 列表转树](go/go-list-to-tree.md) diff --git a/content/go/_index.md b/content/go/_index.md index 94cdb20b..e689aa52 100644 --- a/content/go/_index.md +++ b/content/go/_index.md @@ -10,6 +10,8 @@ [Golang 不同平台架构编译](go-cross-complie.md) +[Golang 守护进程](go-daemon.md) + [Golang 生成证书](go-gen-cert.md) [go:linkname 指令](go-linkname.md) diff --git a/content/go/go-cross-complie.md b/content/go/go-cross-complie.md index 6cdc54a7..96e587ab 100644 --- a/content/go/go-cross-complie.md +++ b/content/go/go-cross-complie.md @@ -32,4 +32,4 @@ CGO_ENABLED=0 GOOS=windows GOARCH=arm64 go build main.go --- [« Golang 密钥对、数字签名和证书管理](go-cert-management.md) -[» Golang 生成证书](go-gen-cert.md) +[» Golang 守护进程](go-daemon.md) diff --git a/content/go/go-daemon.md b/content/go/go-daemon.md new file mode 100644 index 00000000..037d6291 --- /dev/null +++ b/content/go/go-daemon.md @@ -0,0 +1,125 @@ +[🏠 首页](../_index.md) / [Golang 编程](_index.md) / Golang 守护进程 + +# Golang 守护进程 + +在 Go 中编写后台运行的程序(Daemon)的常见步骤涉及到以下几个方面: + +1. **创建守护进程**: + +守护进程是一个在后台运行、不受用户交互影响的程序。你可以通过调用 syscall 包中的一些系统调用让 Go 程序变为后台运行的守护进程。 + +示例代码: + +```go +package main + +import ( +    "fmt" +    "os" +    "syscall" +) + +func main() { +    // Fork出一个子进程_ +    if syscall.ForkExec(os.Args[0], os.Args, &syscall.ProcAttr{}) != nil { +        os.Exit(0) // 父进程退出,子进程继续_ +    } + +    // 继续子进程的逻辑_ +    fmt.Println("程序已经后台运行") +    // 主逻辑_ +    for { +        // 在这里执行你的后台任务_ +    } +} +``` + +2. **日志和输出重定向**: + +后台程序通常不会直接输出到终端,而是将输出重定向到日志文件或 `/dev/null`。 + +示例: + + +```go +package main + +import ( +    "os" +    "os/exec" +    "syscall" +) + +func main() { +    // 设置日志文件或将输出重定向_ +    file, err := os.OpenFile("/tmp/daemon.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) +    if err != nil { +        panic(err) +    } +    defer file.Close() + +    // 设置子进程的文件描述符_ +    attr := &syscall.ProcAttr{ +        Files: []uintptr{file.Fd(), file.Fd(), file.Fd()}, +    } +    +    if _, err := syscall.ForkExec(os.Args[0], os.Args, attr); err != nil { +        panic(err) +    } +    os.Exit(0) // 退出父进程,子进程继续后台运行_ +} +``` + +3. 使用 `nohup` 命令运行: + +如果不想修改代码,可以直接在启动时使用 Linux 提供的 `nohup` 命令运行 Go 程序,使其不依赖终端,并自动重定向输出: + +```bash +nohup ./your_go_program > output.log 2>&1 & +``` + +4. 使用第三方库(如 daemon 包): + +如果觉得自己管理后台运行逻辑比较麻烦,可以使用一些库,如 `github.com/sevlyar/go-daemon`,简化守护进程的实现。 + +示例: + +```go +package main + +import ( +    "fmt" +    "github.com/sevlyar/go-daemon" +) + +func main() { +    cntxt := &daemon.Context{ +        PidFileName: "sample.pid", +        PidFilePerm: 0644, +        LogFileName: "sample.log", +        LogFilePerm: 0640, +        WorkDir:     "./", +        Umask:       027, +    } + +    d, err := cntxt.Reborn() +    if err != nil { +        fmt.Println("无法启动后台进程:", err) +        return +    } +    +    if d != nil { +        return +    } +    defer cntxt.Release() + +    fmt.Println("后台进程运行中") +    // 执行你的后台任务_ +} +``` + +你可以根据你的需求选择合适的方法让 Go 程序后台运行。如果你有更具体的需求,欢迎提供更多细节。 +--- +[« Golang 不同平台架构编译](go-cross-complie.md) + +[» Golang 生成证书](go-gen-cert.md) diff --git a/content/go/go-gen-cert.md b/content/go/go-gen-cert.md index 61b3c9c5..13bb493d 100644 --- a/content/go/go-gen-cert.md +++ b/content/go/go-gen-cert.md @@ -183,6 +183,6 @@ func DomainSign(ips []string, domains ...string) ([]byte, []byte, []byte, error) ``` --- -[« Golang 不同平台架构编译](go-cross-complie.md) +[« Golang 守护进程](go-daemon.md) [» go:linkname 指令](go-linkname.md)