package main import ( "fmt" "os" "os/signal" "syscall" "dubbo.apache.org/dubbo-go/v3/client" _ "dubbo.apache.org/dubbo-go/v3/imports" "github.com/gin-gonic/gin" "github.com/topfans/backend/gateway/config" "github.com/topfans/backend/gateway/router" "github.com/topfans/backend/pkg/logger" "go.uber.org/zap" docs "github.com/topfans/backend/gateway/docs" ) // @title TopFans API // @version 1.0 // @description TopFans 后端 API 文档 - 微服务架构 Gateway 层 // @host localhost:8080 // @basePath /api/v1 // @securityDefinitions.apikey BearerAuth // @in header // @name Authorization // @schemes http func main() { // 1. 初始化日志 if err := logger.Init(logger.Config{ ServiceName: "gateway", Environment: "development", LogLevel: "info", LogPath: "logs", }); err != nil { fmt.Printf("Failed to initialize logger: %v\n", err) os.Exit(1) } defer logger.Logger.Sync() logger.Logger.Info("Starting Top-Fans Gateway...") // 2. 加载配置 cfg := config.Load() if err := cfg.Validate(); err != nil { logger.Logger.Fatal("Invalid configuration", zap.Error(err)) } // 覆盖 Swagger 的 BasePath,避免出现 /api/v1/api/v1 前綴重複 // Swagger 內的 paths 已經包含 /api/v1/...,這裡設為空即可 docs.SwaggerInfo.BasePath = "" logger.Logger.Info("Configuration loaded", zap.String("port", cfg.Server.Port), zap.String("mode", cfg.Server.Mode), zap.String("user_service_url", cfg.Dubbo.UserServiceURL), zap.String("social_service_url", cfg.Dubbo.SocialServiceURL), zap.String("asset_service_url", cfg.Dubbo.AssetServiceURL), zap.String("gallery_service_url", cfg.Dubbo.GalleryServiceURL), zap.String("activity_service_url", cfg.Dubbo.ActivityServiceURL), ) // 3. 设置 Gin 模式 gin.SetMode(cfg.Server.Mode) // 4. 初始化 Dubbo Clients logger.Logger.Info("Connecting to Dubbo services...") // 4.1 UserService Client userClient, err := client.NewClient( client.WithClientURL(cfg.Dubbo.UserServiceURL), ) if err != nil { logger.Logger.Fatal("Failed to create User Service Dubbo client", zap.Error(err)) } logger.Logger.Info("User Service Dubbo client connected successfully") // 4.2 SocialService Client socialClient, err := client.NewClient( client.WithClientURL(cfg.Dubbo.SocialServiceURL), ) if err != nil { logger.Logger.Fatal("Failed to create Social Service Dubbo client", zap.Error(err)) } logger.Logger.Info("Social Service Dubbo client connected successfully") // 4.3 AssetService Client assetClient, err := client.NewClient( client.WithClientURL(cfg.Dubbo.AssetServiceURL), ) if err != nil { logger.Logger.Fatal("Failed to create Asset Service Dubbo client", zap.Error(err)) } logger.Logger.Info("Asset Service Dubbo client connected successfully") // 4.4 GalleryService Client galleryClient, err := client.NewClient( client.WithClientURL(cfg.Dubbo.GalleryServiceURL), ) if err != nil { logger.Logger.Fatal("Failed to create Gallery Service Dubbo client", zap.Error(err)) } logger.Logger.Info("Gallery Service Dubbo client connected successfully") // 4.5 ActivityService Client activityClient, err := client.NewClient( client.WithClientURL(cfg.Dubbo.ActivityServiceURL), ) if err != nil { logger.Logger.Fatal("Failed to create Activity Service Dubbo client", zap.Error(err)) } logger.Logger.Info("Activity Service Dubbo client connected successfully") // 5. 设置路由 logger.Logger.Info("Setting up routes...") r, err := router.SetupRouter(userClient, socialClient, assetClient, galleryClient, activityClient) if err != nil { logger.Logger.Fatal("Failed to setup router", zap.Error(err)) } logger.Logger.Info("Routes configured successfully") // 6. 启动服务器 addr := ":" + cfg.Server.Port logger.Logger.Info("Starting HTTP server", zap.String("address", addr)) // 优雅关闭 go func() { if err := r.Run(addr); err != nil { logger.Logger.Fatal("Failed to start server", zap.Error(err)) } }() logger.Logger.Info("Gateway server started successfully", zap.String("address", fmt.Sprintf("http://localhost%s", addr)), ) // 7. 等待中断信号 quit := make(chan os.Signal, 1) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) <-quit logger.Logger.Info("Shutting down gateway server...") logger.Logger.Info("Gateway server stopped") }