Golang应用作为后台程序运行的实现方式有哪些

Golang应用作为后台程序运行的实现方式有哪些 大家好, 我在后台运行Go程序时遇到了问题。我已经使用"tmux"来运行Go应用,当时没有任何问题,但4-5小时后它(go run main.go)会自动停止。 看起来就像按了ctrl + c一样。

我在本地系统上进行了go build,然后上传到服务器,接着在"tmux"中使用./src(我正确地退出了"tmux")。

请问有什么解决方案可以避免这个问题吗?

提前感谢。

4 回复

尝试处理错误并记录你的操作。如果程序意外停止,很可能是因为出现了 panic。

更多关于Golang应用作为后台程序运行的实现方式有哪些的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


我已经有"错误日志"文件了。从目前看到的情况来看,我没有发现任何错误,当停止Go应用程序时也没有出现任何错误,终端中也没有打印错误信息。

这种情况通常发生在某些条件下,使得未处理的错误返回值被误认为是程序关闭的信号。

请确保在你的程序中处理所有返回的 error

有一个工具可以帮助你完成这个任务,如果我没记错的话,它叫 goreturn

// 代码示例保留原样

在 Go 应用中实现后台运行,有多种可靠的方式。你遇到的问题通常是由于进程管理不当或会话终止导致的。以下是几种推荐的方法:

1. 使用 systemd(推荐用于生产环境)

创建 systemd 服务文件 /etc/systemd/system/your-app.service

[Unit]
Description=Your Go Application
After=network.target

[Service]
Type=simple
User=your-user
WorkingDirectory=/path/to/your/app
ExecStart=/path/to/your/app/binary
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target

启用并启动服务:

sudo systemctl daemon-reload
sudo systemctl enable your-app
sudo systemctl start your-app

2. 使用 nohup 命令

nohup ./your-binary > app.log 2>&1 &

3. 使用 screen 命令

screen -dmS myapp ./your-binary

4. 使用 supervisor

安装 supervisor 后创建配置文件 /etc/supervisor/conf.d/your-app.conf

[program:your-app]
command=/path/to/your/app/binary
directory=/path/to/your/app
autostart=true
autorestart=true
user=your-user
stdout_logfile=/var/log/your-app.log
stderr_logfile=/var/log/your-app.error.log

然后更新 supervisor:

sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start your-app

5. 在 Go 代码中实现信号处理

package main

import (
    "context"
    "log"
    "net/http"
    "os"
    "os/signal"
    "syscall"
    "time"
)

func main() {
    server := &http.Server{
        Addr:    ":8080",
        Handler: http.HandlerFunc(handler),
    }

    go func() {
        if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
            log.Fatalf("Server failed: %v", err)
        }
    }()

    // 等待中断信号
    quit := make(chan os.Signal, 1)
    signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
    <-quit

    // 优雅关闭
    ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
    defer cancel()
    
    if err := server.Shutdown(ctx); err != nil {
        log.Fatalf("Server shutdown failed: %v", err)
    }
}

func handler(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Hello World"))
}

针对你的问题的解决方案

首先确保使用编译后的二进制文件而不是 go run

go build -o myapp main.go
./myapp

对于你的场景,推荐使用 systemd 或 supervisor,它们能自动重启崩溃的进程并提供完善的日志管理。避免使用 tmux 作为生产环境的进程管理工具,因为它主要用于终端会话管理而非长期运行的守护进程。

回到顶部