Rust 配置管理实战:用 config crate 读取多格式配置与环境切换
test12026-10-142 次阅读
它能读哪些格式
config crate 把配置来源抽象成一套统一的 Builder:支持 TOML、YAML、JSON、ini,也支持环境变量和命令行参数,并且可以多层合并——比如默认配置 + 环境配置文件 + 环境变量覆盖,越靠后的来源优先级越高。
定义配置结构体
用 serde 的 Deserialize 把配置反序列化成一个强类型结构,取配置时就有编译期保证,拼写错了立刻报错。
use serde::Deserialize;
#[derive(Debug, Deserialize)]
struct Config {
server: ServerConfig,
database: DatabaseConfig,
}
#[derive(Debug, Deserialize)]
struct ServerConfig {
host: String,
port: u16,
}
#[derive(Debug, Deserialize)]
struct DatabaseConfig {
url: String,
max_pool_size: u32,
}
加载多环境配置
先加一个默认文件,再根据当前环境(这里用环境变量 RUN_ENV)叠加对应的配置文件。config 会自动用一个文件里顶层 key 名为环境名的部分做覆盖。
use config::{Config, File, Environment};
fn load_config() -> Result<Config, config::ConfigError> {
let run_env = std::env::var("RUN_ENV").unwrap_or_else(|_| "dev".into());
let cfg = Config::builder()
.add_source(File::with_name("config/default"))
.add_source(File::with_name(&format!("config/{}", run_env)).required(false))
.add_source(Environment::with_prefix("APP").separator("__"))
.build()?;
Ok(cfg)
}
环境变量覆盖
上面 Environment 配置了 APP__ 前缀,那么环境变量 APP__DATABASE__URL 会覆盖 config 文件里的 database.url。双层下划线被当成层级分隔,非常适合容器环境用环境变量注入密钥。
// config/default.toml
[server]
host = "127.0.0.1"
port = 8080
[database]
url = "sqlite://local.db"
max_pool_size = 8
# 运行时覆盖数据库地址
APP__DATABASE__URL="postgres://user:pass@db:5432/app" RUN_ENV=prod ./app
反序列化成强类型并使用
最终调用 try_deserialize,拿到的是一个 Rust 结构体,后续代码全程用字段访问,不会出现字符串 key 到处飘。
fn main() -> Result<(), Box<dyn std::error::Error>> {
let settings = load_config()?.try_deserialize::<Config>()?;
println!("listen on {}:{}", settings.server.host, settings.server.port);
println!("db pool = {}", settings.database.max_pool_size);
Ok(())
}
可选的热更新
如果希望配置变更不用重启,config crate 本身不带 watch,可以配合 notify 监听文件变化后重新 build 一份。大多数服务用信号(如收到 SIGHUP 重新加载)就够用,避免过度设计。
T
test1
文章作者
它能读哪些格式 config crate 把配置来源抽象成一套统一的 Builder:支持 TOML、YAML、JSO...
- 分类
- 技术
- 发布时间
- 2026-10-14
- 字数
- 约 1876 字
- 阅读
- 2 次
