Golang中如何使用flag和viper配置多环境Web应用

Golang中如何使用flag和viper配置多环境Web应用 我是Go编程语言的新手,希望搭建一个使用viper包和flag来将环境变量解析到我的应用程序中的Web应用。

示例

 $ go run main.go -env=production
1 回复

更多关于Golang中如何使用flag和viper配置多环境Web应用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Golang中结合flag和viper实现多环境配置是常见的实践方案。以下是具体实现示例:

1. 项目结构

config/
├── config.go
├── development.yaml
├── production.yaml
└── test.yaml
main.go

2. 配置文件示例

development.yaml:

server:
  port: 8080
  host: "localhost"
database:
  host: "localhost"
  port: 5432
  name: "dev_db"
  user: "dev_user"

production.yaml:

server:
  port: 80
  host: "0.0.0.0"
database:
  host: "db.production.com"
  port: 5432
  name: "prod_db"
  user: "prod_user"

3. 配置加载代码

config/config.go:

package config

import (
    "fmt"
    "log"
    "github.com/spf13/viper"
)

type Config struct {
    Server   ServerConfig
    Database DatabaseConfig
}

type ServerConfig struct {
    Port int    `mapstructure:"port"`
    Host string `mapstructure:"host"`
}

type DatabaseConfig struct {
    Host string `mapstructure:"host"`
    Port int    `mapstructure:"port"`
    Name string `mapstructure:"name"`
    User string `mapstructure:"user"`
}

func LoadConfig(env string) (*Config, error) {
    viper.SetConfigName(env) // 配置文件名称
    viper.SetConfigType("yaml")
    viper.AddConfigPath("./config") // 配置文件路径
    viper.AddConfigPath(".") // 当前目录
    
    // 设置环境变量前缀并自动绑定
    viper.SetEnvPrefix("APP")
    viper.AutomaticEnv()
    
    // 读取配置文件
    if err := viper.ReadInConfig(); err != nil {
        return nil, fmt.Errorf("failed to read config file: %w", err)
    }
    
    var config Config
    if err := viper.Unmarshal(&config); err != nil {
        return nil, fmt.Errorf("failed to unmarshal config: %w", err)
    }
    
    log.Printf("Loaded %s configuration from %s", env, viper.ConfigFileUsed())
    return &config, nil
}

4. 主程序入口

main.go:

package main

import (
    "flag"
    "log"
    "net/http"
    "your-project/config"
)

func main() {
    // 定义命令行参数
    env := flag.String("env", "development", "运行环境 (development|test|production)")
    flag.Parse()
    
    // 加载配置
    cfg, err := config.LoadConfig(*env)
    if err != nil {
        log.Fatalf("Failed to load config: %v", err)
    }
    
    // 使用配置启动Web服务器
    addr := fmt.Sprintf("%s:%d", cfg.Server.Host, cfg.Server.Port)
    log.Printf("Starting %s server on %s", *env, addr)
    
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Running in %s environment\n", *env)
        fmt.Fprintf(w, "Database: %s@%s:%d/%s", 
            cfg.Database.User, 
            cfg.Database.Host, 
            cfg.Database.Port, 
            cfg.Database.Name)
    })
    
    if err := http.ListenAndServe(addr, nil); err != nil {
        log.Fatalf("Server failed: %v", err)
    }
}

5. 环境变量覆盖示例

可以通过环境变量覆盖配置文件中的值:

# 使用环境变量覆盖数据库主机
export APP_DATABASE_HOST="custom.host.com"
go run main.go -env=production

6. 使用示例

# 开发环境
go run main.go -env=development

# 测试环境
go run main.go -env=test

# 生产环境
go run main.go -env=production

# 带环境变量覆盖
APP_DATABASE_PORT=5433 go run main.go -env=production

这个方案通过flag解析命令行参数指定环境,viper加载对应环境的配置文件,并支持环境变量覆盖配置项,实现了灵活的多环境配置管理。

回到顶部