处理特定于系统的信息在版本控制下的最佳实践是什么?

6
我对版本控制不熟悉,如果这个问题有已知的解决方案,我表示歉意。特别是针对这个问题,我正在使用git,但我很好奇如何处理所有版本控制系统的问题。
我正在开发一个Web应用程序,其中定义了Web应用程序的绝对路径名称(而不是文档根目录)两次。在生产服务器上,此路径不同。我对如何处理此事感到困惑。
我可以选择:
1.重新配置开发服务器以共享与生产相同的路径 2.每次更新生产时编辑两个出现的位置。
我不喜欢#1,因为我宁愿保持应用程序的灵活性以适应任何未来的更改。我不喜欢#2,因为如果我开始在第二个开发服务器上进行开发,并使用第三个路径,那么每次提交和更新都必须更改。
最佳处理方法是什么?我想到了以下几点:
1.使用自定义关键字和变量展开(例如,在版本控制属性中设置$PATH$属性并在所有文件中展开)。Git不支持此功能,因为它会导致巨大的性能损失。 2.使用post-update和pre-commit hooks。可能是git的最佳解决方案,但每次查看状态时,它都会报告两个文件已更改。不太干净。 3.从版本控制之外的配置文件中提取路径。然后我必须在所有服务器上将配置文件放置在相同位置。还不如一开始就使用相同的路径。
有没有简单的方法来处理这个问题?我是不是想太多了?
6个回答

12

绝不要硬编码配置数据,如文件系统路径,并强制进行多次部署以匹配配置。这是黑暗面,有很多痛苦。

我发现构建支持多个配置的系统非常有用且易于操作,我通常将配置文件与源代码一起提交到源代码控制中。但是生产环境的配置文件是混淆的(没有真实密码),而开发环境则是模板化的(因此无法覆盖开发人员的配置)。代码始终以与配置无关的方式打包--同一二进制可以在任何地方部署。

不幸的是,大多数语言/开发平台都不支持此操作(不像Ruby on Rails)。因此,您必须自己构建它,程度不同。

总的原则是将间接性合并到您的配置中:在代码中指定查找配置方式,而不是配置本身。并且通常调用多种间接性:用户特定、应用程序特定、机器特定、环境特定。每个配置应该在一个定义良好的位置/方式中找到,并且它们之间应该有非常明确定义的优先级(通常是用户优先于机器优先于应用程序优先于环境)。通常会发现每个可配置设置在一个位置上有自然的家园,但是不要将该依赖性硬编码到您的应用程序中。

我发现设计应用程序能够报告其配置并进行验证非常有价值。在大多数情况下,缺少或无效的配置项应导致应用程序中止。尽可能在启动时执行验证(和中止)=快速失败。仅在可靠使用时才硬编码默认值。

抽象配置访问,使大部分应用程序不知道它来自何处或如何处理。我更喜欢创建“Config”类,将可配置设置作为单独的属性公开(在相关时强类型),然后通过IOC将它们“注入”到应用程序类中。不要让所有应用程序类直接调用所选平台的原始配置框架;抽象是您的朋友。

在大多数企业级(财富500强)组织中,除了该环境的管理员团队外,没有人可以查看生产(甚至测试)环境配置。配置文件从不在发布中部署,而是由管理员团队手动编辑。与代码并排存储在源代码控制中心的相关配置文件绝对不能被检查。管理团队可能会使用源代码控制,但这是他们自己的私人存储库。萨班斯-奥克斯利法和类似的法规也倾向于严格禁止开发人员访问(近乎)生产系统或任何敏感配置数据。设计方法时务必谨慎。

祝愉快。


即使我不同意你对我的答案的评论,但我认为你的评论很有启发性。+1 - VonC

4

您应该始终将历史记录(源代码控制的作用)与部署分开。

部署涉及:

  • 一组已识别的数据(SCM提供的标签或标识非常方便)
  • 处理这些数据的过程(至少将它们复制到正确的位置,但也可以扩展一些压缩文件等等...)

在部署执行的各种操作中,您应包括一个去变量化阶段。

变量是表示任何可能根据部署平台而改变的关键字(可以是用于持续集成的PC,基本同步的linux,用于预生产同步的旧Solaris8以及具有区域的完整F15K Solaris10:简而言之,它可能会发生很多变化)。请参见Jonathan Leffler的答案以获取实际示例。

变量可以表示路径、JVM版本、某些JVM设置等等,您在SCM中放置的内容应该是带有变量的数据,而不是硬编码的设置。

下一步是在可执行文件中包含一种方法来检测设置文件中的任何更改,以便在运行某些参数时进行更新(避免整个“关闭/更改设置/重新启动”序列)。
这意味着存在两种类型的部署变量

  • 静态变量(永远不会更改)
  • 动态变量(最好在运行时会考虑到它们)

请参阅Jonathan Leffler的答案中的评论。在执行期间更改配置是危险的(与其他上下文的交互),但在极少数情况下可能是必要的。 - Rob Williams
我不太同意。也许在你们的生产环境中是这样,但在我们这里不是。当你有一大批服务器需要进行微调时,这种情况并不罕见。请考虑到你可能没有在职业生涯中见过每种生产场景,我知道我没有。 - VonC
罗布·威廉姆斯:“计算机顾问,在各种技术、角色和行业拥有约30年的经验”……好吧,仔细想想,你可能已经见过所有的东西了;)而且我的回答可能写得不太好。 - VonC
1
@VonC:我同意:有些例外对于那些漫游草原的人来说似乎并不是例外。我试图敏感地意识到我们大多数读者可能永远不会看到一个庞大的服务器农场。但希望当他们真正看到时,能够知道如何处理这种例外情况。 - Rob Williams

2
尽可能避免使用绝对路径。
不要依赖当前版本控制系统来执行某些魔法操作 - 未来您可能会更改版本控制系统。
最简单的方法适用于我:拥有“config.live”,而“config”则配置为开发环境。在部署期间,只需将config.live移动到config即可。对于更复杂的配置,可能需要为每个配置创建一个子目录。
一组部署程序是必不可少的 - 因为配置只是其中一个可能不同的区域。
任何更复杂的东西几乎肯定会引起比解决更多问题。

1

使用像Git这样的SCM进行版本控制,以及像Capistrano这样的部署工具进行部署。虽然Capistrano最初是为Ruby on Rails创建的,但完全可以将其用于其他框架和语言。

主要的事情是特定的部署工具将为您提供所有灵活性,以自动化两端的路径等事项。


0

我喜欢 Ruby on Rails 处理这种问题的方式 - 环境特定的配置文件。Rails 支持开发、测试和生产数据库连接 - 由 database.yml 文件中的配置控制。这里有一篇关于创建其他环境特定配置选项的博客文章,虽然是针对 Rails 的,但可能会给你一些关于如何为你的环境做类似事情的想法。http://usablewebapps.com/2008/09/yaml-and-custom-config-for-rails-projects/


0

听起来你的生产代码是一个完整的git仓库,更新生产环境时使用git pull?你可能想尝试一个单独的构建过程,从你的仓库中检出代码并创建一个干净的构建(没有.git文件夹)。你可以有特定于环境的配置文件,其中包含你的路径,这些路径会随着它一起复制或创建。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接