我想知道是否有任何设计模式,指南或记录的widsom /最佳实践来创建“应用程序配置”结构,数据和文件。 我意识到这些问题在一些帖子中已被部分触及,但我希望以下问题能够从另一个方面提示这个话题。
具体来说,我的兴趣在于开发配置设置的层次结构。
是否有任何实际项目具有足够的复杂程度,可以研究其配置?
我的问题不是针对文件的格式或类型(无论是使用平面ini,还是json,xml,...),而是针对如何首先达到配置。
由于
答案 0 :(得分:0)
多次部署(即安装,配置和运行)许多应用程序。例如,可以在开发人员的机器上部署应用程序;然后在一台或多台测试机器上(名称如UAT,Staging或pre-production);然后可能在多台生产机器上。生产中的多个部署可能由于各种原因而出现,例如:
对于应用程序的每个部署,您可能需要一组“大致相似但略有不同”的配置文件。如果使用复制粘贴方法创建这些多组配置文件,则可能导致维护问题。我知道有两种方法可以减少这个问题。
第一种方法是使用Config4*作为配置文件语法(免责声明:我是Config4 *的主要维护者),因为它的语法提供了多种方式,例如“if-then-else” “和”包括“语句,以使配置文件能够适应其部署环境,同时仍然重用常见的 name = value 设置。我建议您阅读 Config4 *入门指南(HTML)的第2章(HTML)和第3章(PDF),以了解其语法概述和API。不幸的是,Murphy's Law声明您的应用程序将使用一些使用除Config4 *以外的东西的第三方库(例如,XML或Java属性文件)进行配置,因此Config4 *将无法帮助您。但是,我认为阅读上述文档仍然是值得的,因为Config4 *的某些功能可能会让人深思。
第二种方法是为每种配置文件编写一个“模板”,其中模板主要包含纯文本,但有一些占位符。下面是一个示例模板配置文件,使用符号${foo}
表示占位符。
serverName = "${serverName}"
listenPort = "${serverPort}"
logDir = "/data/logs/${serverName}";
idleTimeout = "5 minutes";
workingDir = "/tmp";
如果对应用程序使用的所有配置文件执行此操作,那么您可能会发现使用相对较少数量的占位符对模板配置文件执行全局搜索和替换将会产生准备运行特定部署的配置文件。我在一个项目中使用了这种方法,每个部署有超过2000行配置文件,大约60个部署,因此产生了超过100,000行配置文件。要应用于模板文件的搜索和替换数据的行数比从其生成的可随时部署的配置文件少约50倍,因此更易于维护。如果您正在寻找一种简单的方法来对模板文件中的占位符执行全局搜索和替换,那么您可能需要考虑Apache Velocity。
无论您是手写配置文件还是从模板生成配置文件,都是配置文件中数据的运行时验证问题。不幸的是,相对较少的配置文件格式提供了架构验证。我所知道的唯一一个如下。 Config4 *提供了一个易于使用的模式验证引擎(在上面提到的文档的第3章中讨论过)。还有一个schema validation language for JSON。当然,有很多schema validation languages for XML,但它们通常有一个陡峭的学习曲线。
答案 1 :(得分:0)
确保配置应该在运行时(在应用程序启动期间)而不是在应用程序构建/编译阶段读取。你的二进制文件应该始终是相同的,无论它们在哪里运行。
在启动应用程序期间应该接收正确的配置(从文件系统,环境变量,配置服务器等)。另一种可能性是接收(来自同一来源)有关应使用哪种配置的信息,然后加载已捆绑在软件包中的正确配置。第二种选择不太灵活,但可能更容易入手。
能够在开发环境中覆盖特定的配置(例如,通过命令行)非常有用。有时您也可以使用它来快速调试生产问题。但总的来说,我会避免继承和覆盖部分配置,因为它很快就变得难以管理并且看到整套可用属性。我建议将配置分为两部分。一个 - 在所有环境中常见(常量,路径,公司的邮件服务器等),第二个 - 在不同的运行时间(url,db password等)之间变化的东西
你必须记住测试。必须在集成测试期间正确初始化组件。提前考虑或者稍后你将不得不与你的框架作斗争
答案 2 :(得分:0)
我从Ciaran McHale得到的基本观点是,如果一个软件包的最终用户可能有多个部署,那么软件包应该带有一个接口来有效地生成不同的配置文件。您的问题是什么原则应该指导配置文件的底层结构。即使我们创建一个接口,这个问题仍然是相关的,因为它将有助于界面的设计和实现。一个非主观的关键点是配置过程是通用代码对其环境的调整,我们总是可以将环境分为两部分:数字或服务器领域和非数字或应用领域。因此,一般而非主观的事实是配置值可以分为三类:仅依赖于服务器的那些,仅依赖于应用程序的那些以及依赖于两者的那些。我认为在不同的文件中分离这三个类别很重要,特别是如果它们是直接管理的,没有接口。同样,每个文件应该分区,这些部分对应于包与之交互的环境的不同部分:数据库,电子邮件服务器等。如果需要配置模块,它们就像环境的一部分核心 - 同样的原则适用。我的观察是,一些大型系统甚至会为每个部分使用不同的文件。例如,Apache为不同的站点和不同的模块提供不同的conf文件。我想到的另一点是,没有理由不将函数作为第一类对象用作配置值:如果函数需要在不同的服务器或不同的应用程序中以不同的方式定义,那么它就是一个配置值。我想不出任何其他一般原则。