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) } }
二、排查进程终止的可能诱因
检查LXC容器资源限制
LXC容器可能设置了内存、CPU或进程数配额,资源耗尽时会强制终止进程:- 查看容器资源状态:
lxc-info -n <你的容器名> - 查看容器配置文件(通常在
/var/lib/lxc/<容器名>/config),检查是否存在lxc.cgroup.memory.limit_in_bytes这类限制项。
- 查看容器资源状态:
查看完整系统日志
dmesg缓存可能被覆盖,改用journalctl查看全量系统日志:journalctl --since "1 day ago" | grep "10651" journalctl | grep -i "oom\|kill\|terminate"检查文件描述符耗尽
HTTP服务若存在未正确关闭的连接,可能耗尽文件描述符导致进程终止:- 查看当前系统的文件描述符限制:
ulimit -n - 进程运行时查看当前文件描述符使用量:
lsof -p <当前PID> | wc -l - 临时提升限制后重启服务:
ulimit -n 65535 && ./main > app.log 2>&1 &
- 查看当前系统的文件描述符限制:
检查Nginx反向代理日志
查看Nginx的access.log和error.log,确认是否存在超大请求、高频请求等异常触发进程问题。
三、长期稳定性方案:用systemd管理进程
直接后台运行进程无法保证可靠性,用systemd管理可实现自动重启、日志持久化:
- 创建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 - 生效并启动服务:
systemctl daemon-reload systemctl enable my-go-service.service systemctl start my-go-service.service - 查看服务状态与日志:
systemctl status my-go-service.service journalctl -u my-go-service.service
内容的提问来源于stack exchange,提问作者Igor Branitsky
相关产品推荐
相关产品推荐

