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

EKS中Go应用SIGTERM信号优雅关闭日志捕获问题

问题描述

我在EKS环境中删除Pod时,希望捕获Go服务器优雅关闭的日志,但发现Pod收到SIGTERM信号后服务器立即关闭,没有生成预期的优雅关闭相关日志。我已经在Pod配置中设置了terminationGracePeriodSeconds: 180,相关的Go服务器初始化代码如下:

func ServeRequest(configuredRoutes http.Handler) {
    air_logger.SERVER_STARTUP("########## SERVER STARTED ##########")
    server := &http.Server{
        Addr: config.GetConfig().Server.Port,
        Handler: handlers.CORS(
            handlers.AllowedMethods([]string{"OPTIONS", "GET", "POST", "PUT", "PATCH"}),
            handlers.AllowedHeaders([]string{"DNT", "User-Agent", "X-Requested-With", "If-Modified-Since", "Cache-Control",
                "Content-Type", "Range", "Pragma", "X-FourKitesUserId", "X-FourKitesDeviceId", "Authorization", "Expires"}),
            handlers.MaxAge(600),
        )(configuredRoutes),
    }
    done := make(chan bool, 1)
    quit := make(chan os.Signal, 1)
    signal.Notify(quit, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)

    go func() {
        <-quit
        test_logger.Info(context.TODO(), "test-service server is shutting down")

        ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
        defer cancel()

        server.SetKeepAlivesEnabled(false)
        if err := server.Shutdown(ctx); err != nil {
            test_logger.Fatal(ctx, "error in graceful shutdown of the test-service server:", err.Error())
        }
        close(done)
    }()

    if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
        test_logger.Fatal(context.TODO(), "test-service server shutdown with error: ", err.Error())
    }

    test_logger.Info(context.TODO(), "test-service before server shutdown gracefully")
    <-done
    test_logger.Info(context.TODO(), "test-service server shutdown gracefully")
}
排查与解决思路
  • 确认信号传递是否正常:容器中主进程PID必须为1才能直接接收kubelet发送的SIGTERM。如果用shell脚本启动Go程序,要改用exec ./your-go-binary,让Go进程成为PID1,避免shell拦截信号。
  • 调整优雅关闭超时窗口:当前代码中优雅关闭的上下文超时仅设置为5秒,远小于Pod的180秒终止宽限期。建议将超时时间调整为170*time.Second,给剩余请求处理留足时间,同时避免超过kubelet的等待时长。
  • 验证日志输出配置:检查test_logger的日志级别是否开启了Info级,并且日志是否输出到容器的标准输出/标准错误流。EKS的日志采集工具通常只会收集这两个流的内容,如果日志写入了文件,需要调整配置。
  • 添加信号接收调试日志:在信号处理协程的最开头增加一条更醒目的日志,比如test_logger.Info(context.TODO(), "Received SIGTERM/SIGINT, starting graceful shutdown"),确认信号是否真的被捕获到。
  • 检查Pod终止事件:执行kubectl describe pod <pod-name>查看Pod终止时的事件日志,确认kubelet是否正常发送了SIGTERM,以及是否在宽限期内发送了SIGKILL。

内容的提问来源于stack exchange,提问作者Nisha Vijayakumar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 19:53:17