package main import ( "context" "fmt" "github.com/gin-gonic/gin" "github.com/spf13/viper" "go.uber.org/zap" "go_zh/middleware" "go_zh/pkg/logger" "go_zh/router" "net/http" "os" "os/signal" "syscall" "time" ) func main() { // 设置配置文件路径和名称 viper.SetConfigFile("config.json") viper.SetConfigType("json") // 明确指定JSON格式 err := viper.ReadInConfig() // 搜索并读取配置文件 if err != nil { // 处理错误 panic("初始化配置失败: " + err.Error()) } // 初始化日志系统 if err := logger.InitLogger(); err != nil { panic("初始化日志失败: " + err.Error()) } // 确保程序退出前刷新日志缓冲区 defer logger.Sync() // 设置 Gin 模式 gin.SetMode(viper.GetString("app.mode")) // 初始化Gin引擎 engine := gin.Default() engine.Use(middleware.GinLoggerMiddleware()) //日志中间件 engine.Use(middleware.GinRecoveryMiddleware()) //recover中间件 // 设置路由 router.SetupRoutes(engine) // 启动服务 //_ = engine.Run(":8080") srv := &http.Server{ Addr: fmt.Sprintf(":%d", viper.GetInt("app.port")), Handler: engine.Handler(), } // 优雅启动和关闭 startServer(srv) } // startServer 启动服务器 func startServer(srv *http.Server) { // 在goroutine中启动服务器 go func() { zap.L().Info("启动HTTP服务器", zap.String("address", srv.Addr), ) if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { zap.L().Fatal("启动服务器失败", zap.Error(err)) } }() // 等待中断信号 quit := make(chan os.Signal, 1) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) <-quit zap.L().Info("收到关闭信号,开始优雅关闭...") // 创建关闭超时上下文 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() // 关闭服务器 if err := srv.Shutdown(ctx); err != nil { zap.L().Error("服务器关闭失败", zap.Error(err)) } zap.L().Info("服务器已关闭") }