package main import ( "context" "ego/internal/conf" "ego/internal/router" "ego/pkg/logger" "errors" "net/http" "os" "os/signal" "syscall" "time" "github.com/gin-gonic/gin" "go.uber.org/zap" ) // @title EGO API // @version 1.0 // @description EGO 系统 API 文档 // @termsOfService http://swagger.io/terms/ // @contact.name API Support // @contact.url http://www.swagger.io/support // @contact.email support@swagger.io // @license.name Apache 2.0 // @license.url http://www.apache.org/licenses/LICENSE-2.0.html // @host 127.0.0.1:3000 // @BasePath / // @securityDefinitions.apikey BearerAuth // @in header // @name Authorization func main() { // 从配置文件读取配置 if err := conf.Init(); err != nil { logger.Error(nil, "配置初始化失败", zap.Error(err)) os.Exit(1) } // 设置 gin 模式 ginMode := getGinMode() gin.SetMode(ginMode) logger.Info(nil, "Gin模式设置完成", zap.String("mode", ginMode)) // 创建路由 engine := router.NewRouter() // 获取服务端口 port := getServerPort() // 创建HTTP服务器 server := &http.Server{ Addr: port, Handler: engine, ReadTimeout: 15 * time.Second, WriteTimeout: 15 * time.Second, IdleTimeout: 60 * time.Second, } // 在goroutine中启动服务器 go func() { logger.Info(nil, "服务器启动中...", zap.String("addr", port)) if err := server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) { logger.Error(nil, "服务器启动失败", zap.Error(err)) os.Exit(1) } }() logger.Info(nil, "服务器启动成功", zap.String("addr", port)) // 等待中断信号来优雅地关闭服务器 quit := make(chan os.Signal, 1) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) <-quit logger.Info(nil, "收到关闭信号,开始优雅关闭服务器...") // 创建一个5秒超时的context ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() // 优雅关闭HTTP服务器 if err := server.Shutdown(ctx); err != nil { logger.Error(nil, "服务器强制关闭", zap.Error(err)) } else { logger.Info(nil, "HTTP服务器已优雅关闭") } // 关闭其他资源 conf.Close() logger.Info(nil, "服务器关闭完成") } // getGinMode 获取Gin运行模式 func getGinMode() string { mode := os.Getenv("GIN_MODE") if mode == "" { mode = gin.ReleaseMode // 默认为生产模式 } // 验证模式是否有效 switch mode { case gin.DebugMode, gin.ReleaseMode, gin.TestMode: return mode default: logger.Warn(nil, "无效的GIN_MODE,使用默认值", zap.String("invalid_mode", mode), zap.String("default_mode", gin.ReleaseMode)) return gin.ReleaseMode } } // getServerPort 获取服务器端口 func getServerPort() string { port := os.Getenv("SERVER_PORT") if port == "" { port = ":3000" // 默认端口 } // 确保端口格式正确 if port[0] != ':' { port = ":" + port } return port }