You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Golang net/http服务运行一段时间后自动停止问题求助

排查与解决方案

一、补全日志记录,定位退出核心原因

当前程序日志直接输出到终端,后台运行时会丢失关键信息,这是无法定位问题的首要障碍:

  • 启动服务时强制重定向日志到文件,确保所有输出被留存:
    ./main > app.log 2>&1 &
    
  • 优化代码,添加信号捕获与详细日志:原代码仅处理panic,但进程收到SIGTERM/SIGINT等终止信号时不会触发panic,也不会留下日志。修改后的代码如下:
    package main
    
    import (
        "log"
        "net/http"
        "os"
        "os/signal"
        "syscall"
    )
    
    func main() {
        defer func() {
            if g := recover(); g != nil {
                log.Fatalf("panic in main: %v", g)
            }
        }()
    
        // 捕获终止信号并记录日志
        sigChan := make(chan os.Signal, 1)
        signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
        go func() {
            sig := <-sigChan
            log.Printf("Received signal: %v, shutting down gracefully", sig)
            os.Exit(0)
        }()
    
        fs := http.FileServer(http.Dir("static"))
        http.Handle("/", fs)
        http.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
            w.Write([]byte("Text"))
        })
    
        log.Println("Server starting on :8090")
        err := http.ListenAndServe(":8090", nil)
        if err != nil {
            log.Fatalf("ListenAndServe failed: %v", err)
        }
    }
    

二、排查进程终止的可能诱因

  1. 检查LXC容器资源限制
    LXC容器可能设置了内存、CPU或进程数配额,资源耗尽时会强制终止进程:

    • 查看容器资源状态:
      lxc-info -n <你的容器名>
      
    • 查看容器配置文件(通常在/var/lib/lxc/<容器名>/config),检查是否存在lxc.cgroup.memory.limit_in_bytes这类限制项。
  2. 查看完整系统日志
    dmesg缓存可能被覆盖,改用journalctl查看全量系统日志:

    journalctl --since "1 day ago" | grep "10651"
    journalctl | grep -i "oom\|kill\|terminate"
    
  3. 检查文件描述符耗尽
    HTTP服务若存在未正确关闭的连接,可能耗尽文件描述符导致进程终止:

    • 查看当前系统的文件描述符限制:
      ulimit -n
      
    • 进程运行时查看当前文件描述符使用量:
      lsof -p <当前PID> | wc -l
      
    • 临时提升限制后重启服务:
      ulimit -n 65535 && ./main > app.log 2>&1 &
      
  4. 检查Nginx反向代理日志
    查看Nginx的access.log和error.log,确认是否存在超大请求、高频请求等异常触发进程问题。

三、长期稳定性方案:用systemd管理进程

直接后台运行进程无法保证可靠性,用systemd管理可实现自动重启、日志持久化:

  1. 创建systemd服务文件/etc/systemd/system/my-go-service.service:
    [Unit]
    Description=Go HTTP Static File Service
    After=network.target
    
    [Service]
    Type=simple
    User=root
    WorkingDirectory=/path/to/your/app/dir
    ExecStart=/path/to/your/compiled/main
    Restart=on-failure
    RestartSec=5
    StandardOutput=append:/var/log/go-service.log
    StandardError=append:/var/log/go-service.log
    
    [Install]
    WantedBy=multi-user.target
    
  2. 生效并启动服务:
    systemctl daemon-reload
    systemctl enable my-go-service.service
    systemctl start my-go-service.service
    
  3. 查看服务状态与日志:
    systemctl status my-go-service.service
    journalctl -u my-go-service.service
    

内容的提问来源于stack exchange,提问作者Igor Branitsky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 07:34:56