fix: 修复优雅退出超时问题

This commit is contained in:
tbphp
2025-07-14 11:13:44 +08:00
parent f759c17fa0
commit a0b1223818
3 changed files with 26 additions and 4 deletions

View File

@@ -10,6 +10,7 @@ services:
env_file:
- .env
restart: always
stop_grace_period: ${SERVER_GRACEFUL_SHUTDOWN_TIMEOUT:-60}s
depends_on:
mysql:
condition: service_healthy

View File

@@ -169,10 +169,26 @@ func (a *App) Start() error {
func (a *App) Stop(ctx context.Context) {
logrus.Info("Shutting down server...")
if err := a.httpServer.Shutdown(ctx); err != nil {
logrus.Errorf("Server forced to shutdown: %v", err)
}
serverConfig := a.configManager.GetEffectiveServerConfig()
totalTimeout := time.Duration(serverConfig.GracefulShutdownTimeout) * time.Second
// 动态计算 HTTP 关机超时时间,为后台服务固定预留 5 秒
httpShutdownTimeout := totalTimeout - 5*time.Second
// 为 HTTP 服务器的优雅关闭创建一个独立的 context
httpShutdownCtx, cancelHttpShutdown := context.WithTimeout(context.Background(), httpShutdownTimeout)
defer cancelHttpShutdown()
logrus.Debugf("Attempting to gracefully shut down HTTP server (max %v)...", httpShutdownTimeout)
if err := a.httpServer.Shutdown(httpShutdownCtx); err != nil {
logrus.Debugf("HTTP server graceful shutdown timed out as expected, forcing remaining connections to close.")
if closeErr := a.httpServer.Close(); closeErr != nil {
logrus.Errorf("Error forcing HTTP server to close: %v", closeErr)
}
}
logrus.Info("HTTP server has been shut down.")
// 使用原始的总超时 context 继续关闭其他后台服务
stoppableServices := []func(context.Context){
a.cronChecker.Stop,
a.leaderLock.Stop,
@@ -192,7 +208,6 @@ func (a *App) Stop(ctx context.Context) {
}(stopFunc)
}
// Wait for all services to stop, or for the context to be done.
done := make(chan struct{})
go func() {
wg.Wait()

View File

@@ -164,6 +164,12 @@ func (m *Manager) Validate() error {
validationErrors = append(validationErrors, "AUTH_KEY is required and cannot be empty")
}
// Validate GracefulShutdownTimeout and reset if necessary
if m.config.Server.GracefulShutdownTimeout < 10 {
logrus.Warnf("SERVER_GRACEFUL_SHUTDOWN_TIMEOUT value %ds is too short, resetting to minimum 10s.", m.config.Server.GracefulShutdownTimeout)
m.config.Server.GracefulShutdownTimeout = 10
}
if len(validationErrors) > 0 {
logrus.Error("Configuration validation failed:")
for _, err := range validationErrors {