204 lines
5.3 KiB
Go
204 lines
5.3 KiB
Go
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/starbook"
|
|
assetRepo "github.com/topfans/backend/services/assetService/repository"
|
|
"github.com/topfans/backend/services/starbookService/provider"
|
|
"github.com/topfans/backend/services/starbookService/repository"
|
|
"github.com/topfans/backend/services/starbookService/service"
|
|
)
|
|
|
|
var (
|
|
port = flag.Int("port", getEnvInt("PORT", 20005), "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: "starbook-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 Starbook 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)
|
|
}
|
|
|
|
// 初始化 Repository
|
|
registryRepo := repository.NewAssetRegistryRepository(database.GetDB())
|
|
collectionRepo := repository.NewCollectionRepository(database.GetDB())
|
|
activityRepo := repository.NewActivityAssetRepository(database.GetDB())
|
|
assetRepository := assetRepo.NewAssetRepository(database.GetDB())
|
|
|
|
// 初始化 Service
|
|
starbookService := service.NewStarbookService(
|
|
database.GetDB(),
|
|
registryRepo,
|
|
assetRepository,
|
|
collectionRepo,
|
|
activityRepo,
|
|
)
|
|
|
|
// 初始化 Provider
|
|
starbookProvider := provider.NewStarbookProvider(starbookService)
|
|
|
|
// 初始化 Dubbo-go 服务器
|
|
if err := initDubboService(starbookProvider); err != nil {
|
|
logger.Sugar.Fatalf("Failed to initialize Dubbo service: %v", err)
|
|
}
|
|
|
|
// 等待信号(优雅关闭)
|
|
logger.Sugar.Info("Starbook 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.CollectionAsset{},
|
|
&models.ActivityAsset{},
|
|
&models.AssetRegistry{},
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
// initDubboService 初始化 Dubbo 服务
|
|
func initDubboService(starbookProvider *provider.StarbookProvider) error {
|
|
// 启动健康检查 HTTP 服务器
|
|
healthPort := *port + 1000 // e.g., 20005 -> 21005
|
|
healthHandler = health.NewHandler("starbook-service", healthPort)
|
|
healthHandler.Start()
|
|
|
|
// 创建 Dubbo Server
|
|
srv, err := server.NewServer(
|
|
server.WithServerProtocol(
|
|
protocol.WithPort(*port),
|
|
protocol.WithTriple(),
|
|
),
|
|
)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to create Dubbo server: %w", err)
|
|
}
|
|
|
|
// 注册服务
|
|
if err := pb.RegisterStarbookServiceHandler(srv, starbookProvider); err != nil {
|
|
return fmt.Errorf("failed to register StarbookService handler: %w", err)
|
|
}
|
|
|
|
logger.Sugar.Infof("Dubbo-go provider registered successfully, service: topfans.starbook.StarbookService, port: %d", *port)
|
|
|
|
// 在后台启动 Dubbo 服务器
|
|
go func() {
|
|
if err := srv.Serve(); err != nil {
|
|
logger.Sugar.Fatalf("Failed to serve Dubbo: %v", err)
|
|
}
|
|
}()
|
|
|
|
return nil
|
|
}
|
|
|
|
// gracefulShutdown 优雅关闭
|
|
func gracefulShutdown() {
|
|
quit := make(chan os.Signal, 1)
|
|
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
|
|
<-quit
|
|
|
|
logger.Sugar.Info("Shutting down Starbook Service...")
|
|
|
|
// 关闭健康检查服务器
|
|
if healthHandler != nil {
|
|
healthHandler.Stop()
|
|
}
|
|
|
|
// 关闭数据库连接
|
|
if err := database.Close(); err != nil {
|
|
logger.Sugar.Errorf("Error closing database: %v", err)
|
|
}
|
|
|
|
logger.Sugar.Info("Starbook Service stopped")
|
|
}
|