topfans/backend/services/galleryService/main.go

193 lines
6.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
import (
"flag"
"fmt"
"os"
"os/signal"
"strconv"
"syscall"
dubboclient "dubbo.apache.org/dubbo-go/v3/client"
_ "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"
pbAsset "github.com/topfans/backend/pkg/proto/asset"
pbGallery "github.com/topfans/backend/pkg/proto/gallery"
pbUser "github.com/topfans/backend/pkg/proto/user"
rpcclient "github.com/topfans/backend/services/galleryService/client"
"github.com/topfans/backend/services/galleryService/provider"
"github.com/topfans/backend/services/galleryService/repository"
"github.com/topfans/backend/services/galleryService/service"
)
var (
port = flag.Int("port", getEnvInt("PORT", 20001), "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")
assetServiceURL = flag.String("asset-service-url", getEnv("ASSET_SERVICE_URL", "tri://localhost:20003"), "Asset service URL")
userServiceURL = flag.String("user-service-url", getEnv("USER_SERVICE_URL", "tri://localhost:20000"), "User service URL")
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: "gallery-service",
Environment: env,
LogLevel: os.Getenv("LOG_LEVEL"),
}); err != nil {
panic(fmt.Sprintf("Failed to initialize logger: %v", err))
}
defer logger.Sync()
logger.Logger.Info("Starting Gallery Service...")
// 初始化数据库
dbConfig := database.Config{
Host: *dbHost,
Port: *dbPort,
User: *dbUser,
Password: *dbPassword,
DBName: *dbName,
SSLMode: "disable",
TimeZone: "Asia/Shanghai",
}
if err := database.Init(dbConfig); err != nil {
logger.Logger.Fatal(fmt.Sprintf("Failed to initialize database: %v", err))
}
logger.Logger.Info("Database initialized successfully")
// 启动健康检查 HTTP 服务器
healthPort := *port + 1000 // e.g., 20001 -> 21001
healthHandler = health.NewHandler("gallery-service", healthPort)
healthHandler.Start()
// 创建 Repository 层实例
db := database.GetDB()
// 自动迁移展馆相关表booth_slots / exhibitions
if err := db.AutoMigrate(&models.BoothSlot{}, &models.Exhibition{}); err != nil {
logger.Logger.Fatal(fmt.Sprintf("Failed to migrate gallery tables: %v", err))
}
galleryRepo := repository.NewGalleryRepository(db)
logger.Logger.Info("Repository layer initialized")
// 创建 Dubbo 客户端
assetCli, err := dubboclient.NewClient(
dubboclient.WithClientURL(*assetServiceURL),
)
if err != nil {
logger.Logger.Fatal(fmt.Sprintf("Failed to create Asset Service Dubbo client: %v", err))
}
userCli, err := dubboclient.NewClient(
dubboclient.WithClientURL(*userServiceURL),
)
if err != nil {
logger.Logger.Fatal(fmt.Sprintf("Failed to create User Service Dubbo client: %v", err))
}
// 获取 Asset Service RPC 客户端
assetServiceClient, err := pbAsset.NewAssetService(assetCli)
if err != nil {
logger.Logger.Fatal(fmt.Sprintf("Failed to create Asset Service RPC client: %v", err))
}
assetRPCClient := rpcclient.NewAssetRPCClient(assetServiceClient)
logger.Logger.Info("Asset Service RPC client initialized")
// 获取 User Service RPC 客户端
userServiceClient, err := pbUser.NewUserSocialService(userCli)
if err != nil {
logger.Logger.Fatal(fmt.Sprintf("Failed to create User Service RPC client: %v", err))
}
userRPCClient := rpcclient.NewUserRPCClient(userServiceClient)
logger.Logger.Info("User Service RPC client initialized")
// 创建 Service 层实例
galleryService := service.NewGalleryService(galleryRepo, assetRPCClient, userRPCClient)
slotService := service.NewSlotService(galleryRepo, userRPCClient)
exhibitionService := service.NewExhibitionService(galleryRepo, assetRPCClient)
logger.Logger.Info("Service layer initialized")
// 创建并启动清理 Worker注入 assetRPCClient 以便下架时清除点赞记录)
cleanupWorker := service.NewCleanupWorker(galleryRepo, assetRPCClient)
go cleanupWorker.Start()
logger.Logger.Info("Cleanup worker started")
// 创建 Provider 层实例
galleryProvider := provider.NewGalleryProvider(galleryService, slotService, exhibitionService)
logger.Logger.Info("Provider layer initialized")
// 创建 Dubbo 服务器
srv, err := server.NewServer(
server.WithServerProtocol(
protocol.WithPort(*port),
protocol.WithTriple(),
),
)
if err != nil {
logger.Logger.Fatal(fmt.Sprintf("Failed to create Dubbo server: %v", err))
}
// 使用 Triple 协议生成的 RegisterHandler 函数注册服务
if err := pbGallery.RegisterGalleryServiceHandler(srv, galleryProvider); err != nil {
logger.Logger.Fatal(fmt.Sprintf("Failed to register Gallery Service: %v", err))
}
// 启动服务
if err := srv.Serve(); err != nil {
logger.Logger.Fatal(fmt.Sprintf("Failed to start Gallery Service: %v", err))
}
logger.Logger.Info(fmt.Sprintf("Gallery Service started successfully on port %d", *port))
// 等待退出信号
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
logger.Logger.Info("Shutting down Gallery Service...")
// 停止健康检查服务器
if healthHandler != nil {
healthHandler.Stop()
}
// 停止清理 Worker
cleanupWorker.Stop()
logger.Logger.Info("Cleanup worker stopped")
}