| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428 |
- package config
-
- import (
- "fmt"
- "os"
- "path/filepath"
- "sync"
-
- "gopkg.in/yaml.v2"
- )
-
- // ==================== 配置结构体定义 ====================
-
- // Config 应用配置
- type Config struct {
- Database DBConfig `yaml:"database"`
- Redis RedisConfig `yaml:"redis"`
- Doris DorisConfig `yaml:"doris"`
- RabbitMQ RabbitMQConfig `yaml:"rabbitmq"`
- Auth Auth `yaml:"auth"`
- Service Service `yaml:"service"`
- HTTP HTTPConfig `yaml:"http"`
- Micro MicroConfig `yaml:"micro"` // Go Micro配置
- }
-
- // ==================== 各个组件的配置结构 ====================
-
- // RabbitMQConfig RabbitMQ配置
- type RabbitMQConfig struct {
- Host string `yaml:"host"`
- Port int `yaml:"port"`
- Username string `yaml:"username"`
- Password string `yaml:"password"`
- Vhost string `yaml:"vhost"`
- UseTLS bool `yaml:"use_tls"`
- CACert string `yaml:"ca_cert"`
- CertFile string `yaml:"cert_file"`
- KeyFile string `yaml:"key_file"`
- MaxOpenChannels int `yaml:"max_open_channels"`
- ReconnectDelay int `yaml:"reconnect_delay"`
- MaxReconnectAttempts int `yaml:"max_reconnect_attempts"`
- Heartbeat int `yaml:"heartbeat"`
- ChannelSize int `yaml:"channel_size"`
- DefaultExchange string `yaml:"default_exchange"`
- DefaultQueue string `yaml:"default_queue"`
- AutoAck bool `yaml:"auto_ack"`
- Mandatory bool `yaml:"mandatory"`
- Immediate bool `yaml:"immediate"`
- PrefetchCount int `yaml:"prefetch_count"`
- PrefetchSize int `yaml:"prefetch_size"`
- Global bool `yaml:"global"`
- PublisherConfirms bool `yaml:"publisher_confirms"`
- ConfirmTimeout int `yaml:"confirm_timeout"`
- }
-
- // HTTPConfig HTTP客户端配置
- type HTTPConfig struct {
- Timeout int `yaml:"timeout"`
- MaxIdleConns int `yaml:"max_idle_conns"`
- MaxIdleConnsPerHost int `yaml:"max_idle_conns_per_host"`
- IdleConnTimeout int `yaml:"idle_conn_timeout"`
- MaxConnsPerHost int `yaml:"max_conns_per_host"`
- DisableCompression bool `yaml:"disable_compression"`
- DisableKeepAlives bool `yaml:"disable_keep_alives"`
- }
-
- // DBConfig 数据库配置
- type DBConfig struct {
- Type string `yaml:"type"`
- Host string `yaml:"host"`
- Port int `yaml:"port"`
- Username string `yaml:"username"`
- Password string `yaml:"password"`
- Database string `yaml:"database"`
- MaxOpenConns int `yaml:"max_open_conns"`
- MaxIdleConns int `yaml:"max_idle_conns"`
- ConnMaxLifetime int `yaml:"conn_max_lifetime"`
- }
-
- // RedisConfig Redis配置
- type RedisConfig struct {
- Host string `yaml:"host"`
- Port int `yaml:"port"`
- Password string `yaml:"password"`
- DB int `yaml:"db"`
- PoolSize int `yaml:"pool_size"`
- DialTimeout int `yaml:"dial_timeout"`
- ReadTimeout int `yaml:"read_timeout"`
- WriteTimeout int `yaml:"write_timeout"`
- IdleTimeout int `yaml:"idle_timeout"`
- MaxConnAge int `yaml:"max_conn_age"`
- }
-
- // DorisConfig Doris配置
- type DorisConfig struct {
- FEHost string `yaml:"fe_host"`
- FEPort int `yaml:"fe_port"`
- FEUsername string `yaml:"fe_username"`
- FEPassword string `yaml:"fe_password"`
- MySQLHost string `yaml:"mysql_host"`
- MySQLPort int `yaml:"mysql_port"`
- MaxOpenConns int `yaml:"max_open_conns"`
- MaxIdleConns int `yaml:"max_idle_conns"`
- ConnMaxLifetime int `yaml:"conn_max_lifetime"`
- StreamLoadTimeout int `yaml:"stream_load_timeout"`
- BatchSize int `yaml:"batch_size"`
- }
-
- // Auth 认证配置
- type Auth struct {
- Token string `yaml:"token"`
- }
-
- // Service 微服务配置
- type Service struct {
- ServiceName string `yaml:"service_name"`
- ServiceVersion string `yaml:"service_version"`
- ServiceTag string `yaml:"service_tags"`
- Port int `yaml:"port"`
- ReadTimeout int `yaml:"read_timeout"`
- WriteTimeout int `yaml:"write_timeout"`
- IdleTimeout int `yaml:"idle_timeout"`
- TrustedProxies string `yaml:"trusted_proxies"`
- }
-
- // MicroConfig Go Micro微服务配置
- type MicroConfig struct {
- RegistryAddress string `yaml:"registry_address"`
- RegistryType string `yaml:"registry_type"`
- RegistryTimeout int `yaml:"registry_timeout"`
- LBStrategy string `yaml:"lb_strategy"`
- LBCacheTTL int `yaml:"lb_cache_ttl"`
- LBRetries int `yaml:"lb_retries"`
- ClientTimeout int `yaml:"client_timeout"`
- ClientPoolSize int `yaml:"client_pool_size"`
- MaxRetries int `yaml:"max_retries"`
- CircuitEnabled bool `yaml:"circuit_enabled"`
- CircuitTimeout int `yaml:"circuit_timeout"`
- ErrorThreshold int `yaml:"error_threshold"`
- SleepWindow int `yaml:"sleep_window"`
- HealthPath string `yaml:"health_path"`
- HealthInterval int `yaml:"health_interval"`
- HealthTimeout int `yaml:"health_timeout"`
- LogLevel string `yaml:"log_level"`
- EnableDebug bool `yaml:"enable_debug"`
- MetricsEnabled bool `yaml:"metrics_enabled"`
- MetricsAddress string `yaml:"metrics_address"`
- TracerEnabled bool `yaml:"tracer_enabled"`
- TracerAddress string `yaml:"tracer_address"`
- }
-
- // ==================== 配置接口定义 ====================
-
- // IConfig 配置接口
- type IConfig interface {
- GetDatabase() DBConfig
- GetRedis() RedisConfig
- GetDoris() DorisConfig
- GetRabbitMQ() RabbitMQConfig
- GetAuth() Auth
- GetService() Service
- GetHTTP() HTTPConfig
- GetMicro() MicroConfig
-
- IsDatabaseConfigured() bool
- IsRedisConfigured() bool
- IsDorisConfigured() bool
- IsRabbitMQConfigured() bool
- IsHTTPConfigured() bool
- IsAuthConfigured() bool
- IsMicroConfigured() bool
- }
-
- // configWrapper 配置包装器
- type configWrapper struct {
- config *Config
- }
-
- // ==================== 接口实现 ====================
-
- func (cw *configWrapper) GetDatabase() DBConfig {
- return cw.config.Database
- }
-
- func (cw *configWrapper) GetRedis() RedisConfig {
- return cw.config.Redis
- }
-
- func (cw *configWrapper) GetDoris() DorisConfig {
- return cw.config.Doris
- }
-
- func (cw *configWrapper) GetRabbitMQ() RabbitMQConfig {
- return cw.config.RabbitMQ
- }
-
- func (cw *configWrapper) GetAuth() Auth {
- return cw.config.Auth
- }
-
- func (cw *configWrapper) GetService() Service {
- return cw.config.Service
- }
-
- func (cw *configWrapper) GetHTTP() HTTPConfig {
- return cw.config.HTTP
- }
-
- func (cw *configWrapper) GetMicro() MicroConfig {
- return cw.config.Micro
- }
-
- func (cw *configWrapper) IsDatabaseConfigured() bool {
- db := cw.config.Database
- return db.Type != "" &&
- db.Host != "" &&
- db.Port > 0 &&
- db.Username != "" &&
- db.Database != ""
- }
-
- func (cw *configWrapper) IsRedisConfigured() bool {
- redis := cw.config.Redis
- return redis.Host != "" && redis.Port > 0
- }
-
- func (cw *configWrapper) IsDorisConfigured() bool {
- doris := cw.config.Doris
- return doris.FEHost != "" && doris.FEPort > 0
- }
-
- func (cw *configWrapper) IsRabbitMQConfigured() bool {
- rabbit := cw.config.RabbitMQ
- return rabbit.Host != "" && rabbit.Port > 0
- }
-
- func (cw *configWrapper) IsHTTPConfigured() bool {
- httpCfg := cw.config.HTTP
- return httpCfg.Timeout > 0
- }
-
- func (cw *configWrapper) IsAuthConfigured() bool {
- return cw.config.Auth.Token != ""
- }
-
- func (cw *configWrapper) IsMicroConfigured() bool {
- micro := cw.config.Micro
- return micro.RegistryAddress != ""
- }
-
- // ==================== 单例和全局变量 ====================
-
- var (
- instance IConfig
- once sync.Once
- initErr error
- )
-
- // GetConfig 获取配置单例实例
- func GetConfig() IConfig {
- once.Do(func() {
- config, err := loadConfig()
- if err != nil {
- initErr = err
- instance = &configWrapper{config: &Config{}}
- return
- }
- instance = &configWrapper{config: config}
- })
- return instance
- }
-
- // GetInitError 获取初始化错误(如果有)
- func GetInitError() error {
- return initErr
- }
-
- // ==================== 配置文件加载 ====================
-
- // loadConfig 加载配置文件(整合所有默认值)
- func loadConfig() (*Config, error) {
- configFile, err := findConfigFile()
- if err != nil {
- return nil, err
- }
-
- fmt.Printf("✅ Using config file: %s\n", configFile)
-
- // 创建带默认值的配置
- config := &Config{
- Service: Service{
- ServiceName: "myService",
- Port: 8080,
- ReadTimeout: 30,
- WriteTimeout: 30,
- IdleTimeout: 60,
- TrustedProxies: "",
- },
- Redis: RedisConfig{
- Port: 6379,
- DB: 0,
- PoolSize: 10,
- DialTimeout: 5,
- ReadTimeout: 3,
- WriteTimeout: 3,
- IdleTimeout: 300,
- MaxConnAge: 0,
- },
- Doris: DorisConfig{
- FEPort: 8030,
- MySQLPort: 9030,
- MaxOpenConns: 20,
- MaxIdleConns: 10,
- ConnMaxLifetime: 3600,
- StreamLoadTimeout: 30,
- BatchSize: 1000,
- },
- HTTP: HTTPConfig{
- Timeout: 30,
- MaxIdleConns: 100,
- MaxIdleConnsPerHost: 10,
- IdleConnTimeout: 90,
- MaxConnsPerHost: 0,
- DisableCompression: false,
- DisableKeepAlives: false,
- },
- RabbitMQ: RabbitMQConfig{
- Port: 5672,
- Username: "guest",
- Password: "guest",
- Vhost: "/",
- UseTLS: false,
- MaxOpenChannels: 10,
- ReconnectDelay: 5000,
- MaxReconnectAttempts: 10,
- Heartbeat: 30,
- ChannelSize: 100,
- DefaultExchange: "amq.direct",
- DefaultQueue: "",
- AutoAck: false,
- Mandatory: false,
- Immediate: false,
- PrefetchCount: 1,
- PrefetchSize: 0,
- Global: false,
- PublisherConfirms: false,
- ConfirmTimeout: 30,
- },
- Micro: MicroConfig{
- RegistryAddress: "localhost:8500",
- RegistryType: "consul",
- RegistryTimeout: 10,
- LBStrategy: "roundrobin",
- LBCacheTTL: 30,
- LBRetries: 3,
- ClientTimeout: 30,
- ClientPoolSize: 100,
- MaxRetries: 3,
- CircuitEnabled: true,
- CircuitTimeout: 60,
- ErrorThreshold: 5,
- SleepWindow: 5000,
- HealthPath: "/health",
- HealthInterval: 10,
- HealthTimeout: 5,
- LogLevel: "info",
- EnableDebug: false,
- MetricsEnabled: true,
- MetricsAddress: ":9090",
- TracerEnabled: false,
- TracerAddress: "localhost:6831",
- },
- }
-
- // 读取并解析配置文件
- data, err := os.ReadFile(configFile)
- if err != nil {
- return nil, fmt.Errorf("failed to read config file %s: %v", configFile, err)
- }
-
- err = yaml.Unmarshal(data, &config)
- if err != nil {
- return nil, fmt.Errorf("failed to parse config file: %v", err)
- }
-
- return config, nil
- }
-
- // findConfigFile 查找配置文件路径
- func findConfigFile() (string, error) {
- // 1. 可执行文件同目录
- exePath, err := os.Executable()
- if err == nil {
- exeDir := filepath.Dir(exePath)
- configFile := filepath.Join(exeDir, "db.yaml")
- if _, err := os.Stat(configFile); err == nil {
- return configFile, nil
- }
- }
-
- // 2. 环境变量指定路径
- envConfigPath := os.Getenv("DB_CONFIG_PATH")
- if envConfigPath != "" {
- if _, err := os.Stat(envConfigPath); err == nil {
- return envConfigPath, nil
- }
- return "", fmt.Errorf("DB_CONFIG_PATH file not found: %s", envConfigPath)
- }
-
- // 3. 未找到配置文件
- exeDir := "unknown"
- if exePath, err := os.Executable(); err == nil {
- exeDir = filepath.Dir(exePath)
- }
-
- return "", fmt.Errorf(`no configuration file found!
-
- Tried locations:
- 1. Executable directory: %s/db.yaml
- 2. Environment variable: DB_CONFIG_PATH
-
- Solutions:
- - Place db.yaml in the same directory as the executable
- - Or set DB_CONFIG_PATH environment variable to config file path
-
- Example:
- export DB_CONFIG_PATH=/path/to/your/db.yaml`, exeDir)
- }
|