Go 配置管理与环境变量实践
wxk1991 Lv5

Go 配置管理与环境变量实践

Go 服务写到一定规模后,配置管理会变成很现实的问题。端口、数据库地址、Redis 地址、日志级别、第三方密钥,都不能散落在代码里。

这篇文章整理一套简单、可维护的配置写法。


一、先定义配置结构

不要在代码各处直接 os.Getenv。先定义统一结构:

1
2
3
4
5
6
type Config struct {
Env string
Port string
LogLevel string
Database string
}

然后集中加载:

1
2
3
4
5
6
7
8
func LoadConfig() Config {
return Config{
Env: getEnv("APP_ENV", "dev"),
Port: getEnv("PORT", "8080"),
LogLevel: getEnv("LOG_LEVEL", "info"),
Database: getEnv("DATABASE_URL", ""),
}
}

配置统一入口会让排查和测试都轻松很多。


二、提供默认值

1
2
3
4
5
6
7
func getEnv(key, fallback string) string {
value := os.Getenv(key)
if value == "" {
return fallback
}
return value
}

默认值适合端口、日志级别、运行环境。不适合数据库密码、API token 这类敏感配置。


三、必填配置要启动时校验

不要等到处理请求时才发现数据库地址为空。启动阶段就应该校验:

1
2
3
4
5
6
func (c Config) Validate() error {
if c.Database == "" {
return errors.New("DATABASE_URL is required")
}
return nil
}

服务启动失败比运行中随机失败更容易处理。


四、本地开发可以使用 .env

本地开发时,可以用 .env 文件保存环境变量:

1
2
3
APP_ENV=dev
PORT=8080
DATABASE_URL=postgres://user:pass@localhost:5432/app

Go 标准库不自动加载 .env,可以使用 godotenv

1
_ = godotenv.Load()

生产环境不要依赖 .env 文件,推荐由容器、CI/CD、Secret Manager 或部署平台注入。


五、不要把密钥提交到仓库

.env 应该加入 .gitignore。仓库里可以保留 .env.example

1
2
3
APP_ENV=dev
PORT=8080
DATABASE_URL=

这样新人知道需要哪些配置,但不会泄露真实密钥。


六、配置不要过度动态化

很多配置只需要启动时读取一次,比如端口、数据库连接串、日志级别。

如果需要运行时动态调整,就要考虑配置中心、变更通知和回滚策略。不要为了“灵活”让配置来源变得不可追踪。


七、实践建议

Go 配置管理的核心是集中、显式、可校验。

配置结构统一定义,环境变量集中读取,必填项启动时校验,敏感信息不进仓库。做到这些,绝大多数中小型 Go 服务已经足够稳。