部署大规模系统的常见做法是什么?

par*_*rkr 5 deployment release-management

鉴于一个大型软件项目,其中包含以不同语言编写的多个组件,配置文件,配置脚本,环境设置和数据库迁移脚本 - 部署到生产的常见做法是什么?

有什么困难要考虑?可以使用Ant或Maven等工具简化流程吗?如何处理回滚和数据库管理?是否建议在生产环境中使用版本控制?

Ale*_*lli 10

在我看来,你主要询问有关发布工程 AKA的最佳实践和工具- 了解一个主题的"艺术术语"非常重要,因为这样可以更容易地搜索更多信息.

配置管理系统(CMS - 又称版本控制系统或版本控制系统)对于当今的软件开发是必不可少的; 如果您使用一个或多个IDE,那么它们与CMS之间的良好集成也是很好的,尽管这对于开发而言比出于部署/降级的目的更为重要.

从一个重要的角度来看,CMS的关键在于它必须对"分支"(无论名称)提供良好的支持,因为版本必须来自"发布分支",其中所有正在开发的代码及其所有依赖项(代码和数据)处于稳定的"快照"中,从中可以随意再现精确,相同的配置.

如果您必须维护多个分支(针对不同用途,平台,等等)进行定制,那么对良好分支支持的需求可能会更加明显,但即使您的版本始终严格按照单个线性顺序排列,更新的最佳实践仍然要求发布分支."良好的分支支持"包括易于合并(以及对文件进行不同更改时的"冲突解决"),"挑选樱桃"(从一个分支或头部/主干获取一个补丁或变更集,并将其应用于另一个分支)等.

在实践中,您通过创建发布分支来开始发布过程; 然后,您在该分支上运行详尽的测试(通常比您在持续构建中每天运行的更多 - 包括广泛的回归测试,集成测试,负载测试,性能验证等,以及可能甚至更昂贵的质量保证流程,具体取决于).如果详尽的测试和QA揭示候选版本中的缺陷(包括回归,性能下降等),则必须修复它们; 在一个大型团队中,头部/主干的开发可能在QA完成时继续进行,因此需要易于挑选/合并/等(无论您的练习是在头部还是在发布分支上执行修复,它仍然需要合并到另一方;-).

最后但并非最不重要的一点是,除非您以某种方式跟踪您的版本所依赖的"所有内容",否则您无法从CMS获得完全降级价值 - 最简单的方法是使用工具的所有二进制文件的副本或硬链接你需要建立你的发布等,但这往往是不切实际的; 所以至少跟踪使用的那些工具的确切版本,版本,错误修正和数量(操作系统,编译器,系统库,预处理图像,声音或视频文件到最终形式的工具等).关键是能够在需要的时候准确地重现重建建议发布的确切版本所需的环境(否则你会疯狂追踪可能依赖于第三方工具更改的细微错误; 因为它们的版本发生了变化; - ).

在CMS之后,第二个最重要的转换工具是一个很好的问题跟踪系统 - 理想情况下是一个与CMS完美集成的系统.这对于开发过程(以及产品管理的其他方面)也很重要,但就发布过程而言,问题跟踪器的重要性在于能够轻松准确地记录已修复的错误,已添加,删除的功能,或者更改,以及在即将发布的新版本中预期会对性能(或其他用户可观察的特征)进行哪些修改.出于此目的,开发中的关键"最佳实践"是,提交给CMS的每个变更集必须连接到问题跟踪系统中的一个(或多个)问题:毕竟,这个变更必须有一些目的(修复错误,更改功能,优化某些内容或某些内部重构,这些内部重构应该对软件的用户不可见); 类似地,标记为"已关闭"的每个跟踪问题必须连接到一个(或多个)更改集(除非关闭是"不会按预期修复/工作"类型;与第三方组件中的错误和c相关的问题已经由第三方供应商修复的,如果您设法跟踪CMS中的所有第三方组件,也很容易对待,如上所述;如果不这样做,至少应该有文本CMS下的文件记录了第三方组件及其演变,再次见上文,当第三方组件上的某些跟踪问题被关闭时,需要更改这些文件.

自动化各种降级流程(包括构建,自动化测试和部署任务)是第三要务 - 自动化流程比要求一些贫困人员手动完成一系列步骤(对于足够复杂的任务,更高效)和可重复性更高当然,自动化的工作流程可能需要"让人在循环中".正如你所推测的那样,诸如Ant(和SCons等等)之类的工具可以在这里提供帮助,但不可避免地(除非你很幸运能够通过非常简单和直接的过程逃脱)你会发现自己用ad-hoc脚本和c丰富它们(一些强大而灵活的脚本语言,如perl,python,ruby和c,会有所帮助).当您的发布工作流程足够复杂时,"工作流引擎"也很宝贵(例如,涉及特定人员或其团队"签署"QA合规性,法律合规性,UI准则合规性等).

您询问的其他一些具体问题根据您的环境的具体情况而有很大差异.如果你能负担得起程序员的停机时间,你的生活相对容易,即使你正在使用大型数据库,因为你可以按顺序和确定地操作:你正常关闭现有系统,确保保存和备份当前数据库(简化回滚,在希望非常罕见的情况下,它是必需的),运行一次性脚本进行模式迁移或其他"不可逆转的"环境更改,再次以一般用户无法访问的模式重新启动系统,运行另一组广泛的自动化测试 - 最后如果一切顺利(包括在新状态下保存和备份数据库,如果相关),系统再次开放通用.

如果您需要更新"实时"系统,无需停机,这可能会有轻微的不便,也可能是系统性的噩梦.在最好的情况下,事务相当短,并且事务设置的状态之间的同步可能会延迟一点而不会损坏......并且您拥有合理的资源(CPU,存储和c).在这种情况下,您并行运行两个系统 - 旧系统和新系统 - 并确保所有新事务都以新系统为目标,同时让旧系统完成旧系统.当旧系统上的事务终止时,单独的任务会定期将"旧系统中的新数据"同步到新系统.最终,您可以确定旧系统上没有正在运行的任何事务,并且在那里发生的所有更改都会同步到新系统 - 此时您最终可以关闭旧系统.(当然,如果需要回滚更改,您还需要准备好"反向同步").

这是实时系统更新的"简单,甜蜜"的极端; 在另一个极端,您可以发现自己处于一种过度约束的状态,您可以证明任务是不可能的(您无法在逻辑上满足给定资源的所有规定要求).旧系统上的长会话无法终止 - 稀缺的资源使得无法并行运行两个系统 - 每个交易的硬实时同步的核心要求等等都可以使你的生活悲惨(正如我注意到的那样,在极端情况下,可以使所述任务绝对不可能).关于这个你可以做的两件最好的事情:(1)确保你拥有丰富的资源(当一些服务器出乎意料地瘫痪时,这也会拯救你的皮肤......你还会有另一个人来应对紧急情况! - ); (2)从一开始就考虑这种困境,最初定义整个系统的体系结构(例如:偏好短期事务到长期会话,而不是"快照,关闭,并从快照无缝重启" ",是一个很好的arcitectural指针;-).