给应用传递配置,用环境变量?用程序接口选项/API接口选项?还是用配置文件?这是一个好问题!
最开始遇到这个问题时,是因为自己同时遇到这三种实现方式,需要判断应该用那种才是最适合的方式,但当时自己也没有什么依据或准则 :(
搜索了一些博文和参考一些经典程序设计,遂形成一些想法和判断,积累如下 :)
结论先行
- 优先用程序接口选项/API接口选项,此种实现可以保证配置的充分自包和无其它依赖
- 次之用配置文件
- 最后用环境变量。但是,在传递密码配置或运行在容器的场景,环境变量或可优先考虑
接口选项
在长期的Unix/Linux世界实践中,程序接口选项逐渐形成了短配置参数和长配置参数。例如,接口选项对“名称”进行配置,我们可以用短格式 -n HelloWorld ,或更可阅读的长格式--name HelloWorld 。
在选项配置中,还可以细分必须(Required)和可选(Optional),以及是否携带参数。而且为了加快接口选项的输入,某些短配置可以连写,只要仅最后一个参数接收配置。
其中C++网络系统应用框架ACE Framework提供了ACE_Get_Opt类辅助处理此领域,而且实现的相当规范,可以参考
ACE: ACE_Get_Opt Class Reference
对于C/C++服务器端无gui界面程序,ACE Framework更是一个坚固的框架选择。几乎你想到的要实现的东西都有,且默认高效实现,开箱即用!
API接口选项设计思路上雷同,不赘述
配置文件
用文件配置,意味着应用独立性在减弱。建议尽量仅在配置比较复杂时引入,或配置变动比较少且为程序提供脱码的默认值场景使用。
在一些典型程序Redis/vsftpd/sshd/dnsmasq的实践中:
+ 程序提供部分经常使用的接口选项,再辅助以配置文件
+ 接口选项和配置文件,同时提供了相同的配置能力,且文件配置项和命令选项配置名称都是一致的,但命令选项优先!
用配置文件,更倾向于配置复杂的场景,或很少变动的配置,作为独立于程序代码外的默认值提供
配置文件提供与接口选项相同配置项,但配置文件中可以提供详尽的注释,相当于对接口选项提供一份详细的随机说明文档,也是一种不错的经典实践:)
如果您是提供的库代码,用配置文件,就有点不伦不类了,应首先用API接口选项的方式!
环境变量
一般来说,环境变量,最后来说,也就是说它的使用应尽量的少。但在docker容器和云原生之后,环境变量的使用,应得到必要的重视 !
用环境变量配置的使用场景,类似全局变量,一般用于多道程序共享使用,且配置信息可以公开。例如,类似windows中%PATH%、%TMP%等;或配置深度比较深,要避免比较长的传递路径(经常是代码中坏味道)。
用环境变量配置具有一定私密性的场景,利用根安全动态产生环境变量,仅在父子进程和子进程应用程序内存中保存敏感信息,例如,数据库密码等
在容器或云环境中,我们可以用环境变量创造出程序相互隔离的的“平行世界”,用环境变量来进行一些基础性隔离!这些配置,在配置层次上,应该接近“配置树”的根部,是一些根本性的区别!但后续大量的配置,应该通过分布式配置、注册中心进行完成,不然,就误用了环境变量了!