package main import ( "context" "fmt" "net/http" "bindbox-game/configs" "bindbox-game/internal/pkg/env" "bindbox-game/internal/pkg/logger" "bindbox-game/internal/pkg/otel" "bindbox-game/internal/pkg/redis" "bindbox-game/internal/pkg/shutdown" "bindbox-game/internal/pkg/timeutil" "bindbox-game/internal/repository/mysql" "bindbox-game/internal/router" activitysvc "bindbox-game/internal/service/activity" douyinsvc "bindbox-game/internal/service/douyin" gamesvc "bindbox-game/internal/service/game" syscfgsvc "bindbox-game/internal/service/sysconfig" titlesvc "bindbox-game/internal/service/title" usersvc "bindbox-game/internal/service/user" "flag" "go.uber.org/zap" ) // @title mini-chat 接口文档 // @version v0.0.1 // @securityDefinitions.apikey LoginVerifyToken // @in header // @name Authorization // @BasePath / func main() { flag.Parse() // 初始化配置 configs.Init() // 初始化 OpenTelemetry cfg := configs.Get() otelShutdown, err := otel.Init(otel.Config{ ServiceName: configs.ProjectName, ServiceVersion: "1.0.0", Environment: env.Active().Value(), Endpoint: cfg.Otel.Endpoint, Enabled: cfg.Otel.Enabled, }) if err != nil { fmt.Printf("OpenTelemetry init failed: %v\n", err) } // 初始化 MySQL dbRepo, err := mysql.New() if err != nil { panic(err) } // 初始化 自定义 Logger customLogger, err := logger.NewCustomLogger( logger.WithDebugLevel(), // 启用调试级别日志 logger.WithOutputInConsole(), // 启用控制台输出 logger.WithField("domain", fmt.Sprintf("%s[%s]", configs.ProjectName, env.Active().Value())), logger.WithTimeLayout(timeutil.CSTLayout), logger.WithFileRotationP(configs.ProjectAccessLogFile), ) if err != nil { panic(err) } defer func() { _ = customLogger.Sync() }() // 初始化 Redis if err := redis.Init(context.Background(), customLogger); err != nil { customLogger.Warn("Redis init failed, some features may be disabled", zap.Error(err)) } // 初始化 HTTP 服务 mux, cleanup, err := router.NewHTTPMux(customLogger, dbRepo) if err != nil { panic(err) } server := &http.Server{ Addr: configs.ProjectPort, Handler: mux, } go func() { if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed { customLogger.Fatal("http server startup err", zap.Error(err)) } }() activitysvc.StartScheduledSettlement(customLogger, dbRepo, redis.GetClient()) usersvc.StartExpirationCheck(customLogger, dbRepo) usersvc.StartAutoCancelWorker(customLogger, dbRepo) // 启动抖店订单同步定时任务 syscfgSvc := syscfgsvc.New(customLogger, dbRepo) ticketSvc := gamesvc.NewTicketService(customLogger, dbRepo) userSvc := usersvc.New(customLogger, dbRepo) titleSvc := titlesvc.New(customLogger, dbRepo) douyinsvc.StartDouyinOrderSync(customLogger, dbRepo, syscfgSvc, ticketSvc, userSvc, titleSvc) // 初始化全局动态配置服务 if err := syscfgsvc.InitGlobalDynamicConfig(customLogger, dbRepo); err != nil { customLogger.Warn("动态配置加载失败,将使用静态配置", zap.Error(err)) } // 优雅关闭 shutdown.Close( func() { // 清理资源 (Worker) if cleanup != nil { cleanup() } // 关闭 OpenTelemetry if otelShutdown != nil { _ = otelShutdown(context.Background()) } // 关闭 http server if err := server.Shutdown(context.TODO()); err != nil { customLogger.Error("server shutdown err", zap.Error(err)) } // 关闭 db master (支持读写) if err := dbRepo.DbWClose(); err != nil { customLogger.Error("dbw close err", zap.Error(err)) } // 关闭 db slave (仅支持读) if err := dbRepo.DbRClose(); err != nil { customLogger.Error("dbr close err", zap.Error(err)) } }, ) }