2026-05-25 17:50:20 +08:00

151 lines
5.4 KiB
Go

package config
import (
"errors"
"strings"
"hyapp/pkg/configx"
"hyapp/pkg/logx"
)
// Config describes statistics-service dependencies and MQ subscriptions.
type Config struct {
ServiceName string `yaml:"service_name"`
NodeID string `yaml:"node_id"`
Environment string `yaml:"environment"`
HealthHTTPAddr string `yaml:"health_http_addr"`
QueryHTTPAddr string `yaml:"query_http_addr"`
MySQLDSN string `yaml:"mysql_dsn"`
RocketMQ RocketMQConfig `yaml:"rocketmq"`
Log logx.Config `yaml:"log"`
}
type RocketMQConfig struct {
Enabled bool `yaml:"enabled"`
NameServers []string `yaml:"name_servers"`
NameServerDomain string `yaml:"name_server_domain"`
AccessKey string `yaml:"access_key"`
SecretKey string `yaml:"secret_key"`
SecurityToken string `yaml:"security_token"`
Namespace string `yaml:"namespace"`
VIPChannel bool `yaml:"vip_channel"`
WalletOutbox ConsumerMQConfig `yaml:"wallet_outbox"`
RoomOutbox ConsumerMQConfig `yaml:"room_outbox"`
UserOutbox ConsumerMQConfig `yaml:"user_outbox"`
GameOutbox ConsumerMQConfig `yaml:"game_outbox"`
}
type ConsumerMQConfig struct {
Enabled bool `yaml:"enabled"`
Topic string `yaml:"topic"`
ConsumerGroup string `yaml:"consumer_group"`
ConsumerMaxReconsumeTimes int32 `yaml:"consumer_max_reconsume_times"`
}
func Default() Config {
return Config{
ServiceName: "statistics-service",
NodeID: "statistics-local",
Environment: "local",
HealthHTTPAddr: ":13110",
QueryHTTPAddr: ":13010",
MySQLDSN: "hyapp:hyapp@tcp(127.0.0.1:23306)/hyapp_statistics?parseTime=true&charset=utf8mb4&loc=UTC&multiStatements=true",
RocketMQ: defaultRocketMQConfig(),
Log: logx.Config{
Level: "info",
Format: "json",
MaxPayloadBytes: 2048,
},
}
}
func Load(path string) (Config, error) {
cfg := Default()
if path != "" {
if err := configx.LoadYAML(path, &cfg); err != nil {
return Config{}, err
}
}
cfg.ServiceName = strings.TrimSpace(cfg.ServiceName)
if cfg.ServiceName == "" {
cfg.ServiceName = "statistics-service"
}
cfg.NodeID = strings.TrimSpace(cfg.NodeID)
if cfg.NodeID == "" {
cfg.NodeID = cfg.ServiceName
}
cfg.Environment = strings.TrimSpace(cfg.Environment)
if cfg.Environment == "" {
cfg.Environment = "local"
}
cfg.HealthHTTPAddr = strings.TrimSpace(cfg.HealthHTTPAddr)
if cfg.HealthHTTPAddr == "" {
cfg.HealthHTTPAddr = ":13110"
}
cfg.QueryHTTPAddr = strings.TrimSpace(cfg.QueryHTTPAddr)
if cfg.QueryHTTPAddr == "" {
cfg.QueryHTTPAddr = ":13010"
}
cfg.RocketMQ = normalizeRocketMQConfig(cfg.RocketMQ)
if cfg.RocketMQ.Enabled {
if len(cfg.RocketMQ.NameServers) == 0 && cfg.RocketMQ.NameServerDomain == "" {
return Config{}, errors.New("rocketmq name_servers or name_server_domain is required")
}
if (cfg.RocketMQ.AccessKey == "") != (cfg.RocketMQ.SecretKey == "") {
return Config{}, errors.New("rocketmq access_key and secret_key must be configured together")
}
}
return cfg, nil
}
func defaultRocketMQConfig() RocketMQConfig {
return RocketMQConfig{
Enabled: false,
WalletOutbox: ConsumerMQConfig{Enabled: false, Topic: "hyapp_wallet_outbox", ConsumerGroup: "hyapp-statistics-wallet-outbox", ConsumerMaxReconsumeTimes: 16},
RoomOutbox: ConsumerMQConfig{Enabled: false, Topic: "hyapp_room_outbox", ConsumerGroup: "hyapp-statistics-room-outbox", ConsumerMaxReconsumeTimes: 16},
UserOutbox: ConsumerMQConfig{Enabled: false, Topic: "hyapp_user_outbox", ConsumerGroup: "hyapp-statistics-user-outbox", ConsumerMaxReconsumeTimes: 16},
GameOutbox: ConsumerMQConfig{Enabled: false, Topic: "hyapp_game_outbox", ConsumerGroup: "hyapp-statistics-game-outbox", ConsumerMaxReconsumeTimes: 16},
}
}
func normalizeRocketMQConfig(cfg RocketMQConfig) RocketMQConfig {
defaults := defaultRocketMQConfig()
cfg.NameServers = normalizeStringSlice(cfg.NameServers)
cfg.NameServerDomain = strings.TrimSpace(cfg.NameServerDomain)
cfg.AccessKey = strings.TrimSpace(cfg.AccessKey)
cfg.SecretKey = strings.TrimSpace(cfg.SecretKey)
cfg.SecurityToken = strings.TrimSpace(cfg.SecurityToken)
cfg.Namespace = strings.TrimSpace(cfg.Namespace)
cfg.WalletOutbox = normalizeConsumer(cfg.WalletOutbox, defaults.WalletOutbox)
cfg.RoomOutbox = normalizeConsumer(cfg.RoomOutbox, defaults.RoomOutbox)
cfg.UserOutbox = normalizeConsumer(cfg.UserOutbox, defaults.UserOutbox)
cfg.GameOutbox = normalizeConsumer(cfg.GameOutbox, defaults.GameOutbox)
if cfg.WalletOutbox.Enabled || cfg.RoomOutbox.Enabled || cfg.UserOutbox.Enabled || cfg.GameOutbox.Enabled {
cfg.Enabled = true
}
return cfg
}
func normalizeConsumer(cfg ConsumerMQConfig, defaults ConsumerMQConfig) ConsumerMQConfig {
if cfg.Topic = strings.TrimSpace(cfg.Topic); cfg.Topic == "" {
cfg.Topic = defaults.Topic
}
if cfg.ConsumerGroup = strings.TrimSpace(cfg.ConsumerGroup); cfg.ConsumerGroup == "" {
cfg.ConsumerGroup = defaults.ConsumerGroup
}
if cfg.ConsumerMaxReconsumeTimes <= 0 {
cfg.ConsumerMaxReconsumeTimes = defaults.ConsumerMaxReconsumeTimes
}
return cfg
}
func normalizeStringSlice(values []string) []string {
normalized := make([]string, 0, len(values))
for _, value := range values {
if value = strings.TrimSpace(value); value != "" {
normalized = append(normalized, value)
}
}
return normalized
}