package main import ( "flag" "fmt" "os" "os/signal" "strconv" "syscall" _ "dubbo.apache.org/dubbo-go/v3/imports" "dubbo.apache.org/dubbo-go/v3/protocol" "dubbo.apache.org/dubbo-go/v3/server" "github.com/topfans/backend/pkg/database" "github.com/topfans/backend/pkg/health" "github.com/topfans/backend/pkg/logger" "github.com/topfans/backend/pkg/models" pb "github.com/topfans/backend/pkg/proto/user" "github.com/topfans/backend/services/userService/provider" "github.com/topfans/backend/services/userService/repository" "github.com/topfans/backend/services/userService/service" ) var ( port = flag.Int("port", getEnvInt("PORT", 20000), "Dubbo service port") dbHost = flag.String("db-host", getEnv("DB_HOST", "localhost"), "Database host") dbPort = flag.Int("db-port", getEnvInt("DB_PORT", 5432), "Database port") dbUser = flag.String("db-user", getEnv("DB_USER", "postgres"), "Database user") dbPassword = flag.String("db-password", getEnv("DB_PASSWORD", ""), "Database password") dbName = flag.String("db-name", getEnv("DB_NAME", "top-fans"), "Database name") healthHandler *health.Handler ) func getEnv(key, fallback string) string { if v := os.Getenv(key); v != "" { return v } return fallback } func getEnvInt(key string, fallback int) int { if v := os.Getenv(key); v != "" { if n, err := strconv.Atoi(v); err == nil { return n } } return fallback } func main() { flag.Parse() // 初始化日志(必须在最前面) env := os.Getenv("ENV") if env == "" { env = "development" } if err := logger.Init(logger.Config{ ServiceName: "user-service", Environment: env, LogLevel: os.Getenv("LOG_LEVEL"), }); err != nil { panic(fmt.Sprintf("Failed to initialize logger: %v", err)) } defer logger.Sync() logger.Sugar.Info("Starting User Service...") // 初始化数据库 if err := initDatabase(); err != nil { logger.Sugar.Fatalf("Failed to initialize database: %v", err) } // 自动迁移数据库表 if err := autoMigrate(); err != nil { logger.Sugar.Fatalf("Failed to migrate database: %v", err) } // 初始化 Dubbo-go 服务器 if err := initDubboService(); err != nil { logger.Sugar.Fatalf("Failed to initialize Dubbo service: %v", err) } // 等待信号(优雅关闭) logger.Sugar.Info("Dubbo-go service started successfully. Press Ctrl+C to exit.") gracefulShutdown() } // initDatabase 初始化数据库连接 func initDatabase() error { config := database.Config{ Host: *dbHost, Port: *dbPort, User: *dbUser, Password: *dbPassword, DBName: *dbName, SSLMode: "disable", TimeZone: "Asia/Shanghai", } return database.Init(config) } // autoMigrate 自动迁移数据库表 func autoMigrate() error { db := database.GetDB() if db == nil { return fmt.Errorf("database is not initialized") } // 按顺序迁移(考虑外键依赖) tables := []interface{}{ &models.Star{}, &models.User{}, &models.FanProfile{}, } for _, table := range tables { if err := db.AutoMigrate(table); err != nil { return fmt.Errorf("failed to migrate table: %w", err) } } logger.Sugar.Info("Database migration completed successfully") return nil } // gracefulShutdown 优雅关闭 func gracefulShutdown() { quit := make(chan os.Signal, 1) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) <-quit logger.Sugar.Info("Shutting down server...") // 关闭健康检查服务器 if healthHandler != nil { healthHandler.Stop() } // 关闭数据库连接 if err := database.Close(); err != nil { logger.Sugar.Errorf("Error closing database: %v", err) } logger.Sugar.Info("Server exited") } // initDubboService 初始化Dubbo-go服务 func initDubboService() error { // 启动健康检查 HTTP 服务器 healthPort := *port + 1000 // e.g., 20000 -> 21000 healthHandler = health.NewHandler("user-service", healthPort) healthHandler.Start() db := database.GetDB() if db == nil { return fmt.Errorf("database is not initialized") } // 创建Repository实例 userRepo := repository.NewUserRepository() fanProfileRepo := repository.NewFanProfileRepository() starRepo := repository.NewStarRepository() // 创建Service实例 authService := service.NewAuthService(userRepo, fanProfileRepo, starRepo, db) userService := service.NewUserService(userRepo, fanProfileRepo, db) identityService := service.NewIdentityService(fanProfileRepo, starRepo, userRepo, db) // 创建Provider实例 authProvider := provider.NewAuthProvider(authService) userProvider := provider.NewUserProvider(userService, identityService) // 创建统一Provider实例(作为集成层,委托给其他Provider) unifiedProvider := provider.NewUnifiedProvider(authProvider, userProvider) // 使用编程式注册方式(参考 dubbo-go-samples/helloworld) // 创建 Dubbo Server srv, err := server.NewServer( server.WithServerProtocol( protocol.WithPort(20000), protocol.WithTriple(), ), ) if err != nil { return fmt.Errorf("failed to create Dubbo server: %w", err) } // 使用 Triple 协议生成的 RegisterHandler 函数注册服务 if err := pb.RegisterUserSocialServiceHandler(srv, unifiedProvider); err != nil { return fmt.Errorf("failed to register UserSocialService handler: %w", err) } logger.Sugar.Info("Dubbo-go unified provider registered successfully", "service", "topfans.user.UserSocialService", "port", 20000, ) // 在后台启动 Dubbo 服务器 go func() { if err := srv.Serve(); err != nil { logger.Sugar.Fatalf("Failed to serve Dubbo: %v", err) } }() return nil }