【问题标题】:What is the best way to handle release management for software with multiple versions?处理具有多个版本的软件的发布管理的最佳方式是什么?
【发布时间】:2010-11-17 00:04:48
【问题描述】:

我的公司为房地产机构构建了一个 Web 应用程序——最初使用经典 ASP 编码,并逐渐迁移到 .NET。本质上,它是一个带有后端数据库的网站,混合了自定义 Windows 服务/dll。 .NET 应用程序的标准。

在我过去的公司中,我们有一个传统的软件设计生命周期。我们构建了我们的产品版本,当我们发布时,所有客户都收到了相同的代码。产品需求通过我们的工程团队过滤,发送给 QA 以在本地暂存环境中进行测试,然后推送到生产环境。

这家公司为多个客户提供我们产品的多个版本。基本上,客户 A 可以使用 1.5 版本,客户 B 可以使用 1.6,客户 C 可以使用 2.0。我们这样做是因为使用我们的应用程序的机构对影响其用户的任何变化都有严格的要求。如果客户对 1.5 版感到满意,他们会留在那里,即使 2.0 版拥有所有最新的花里胡哨。客户实际上推迟了升级,因为新的“功能”实际上会造成混乱,从而伤害了他们的用户群。

在您还小的时候支持这种类型的生命周期很好,但是当您发展到数十或数百名客户时,这对我们的开发人员、DBA、质量检查人员来说是一种压力,更不用说我们的支持团队了。现在我们的情况是,我们每周只能安排 6-8 个站点,这些站点可以根据需求进行更新。这迫使我们让其他站点等待 2-4 个月才能在他们的站点上获得哪怕是很小的更新。任何需要立即关注的生产问题或错误都会使事情变得更加糟糕——因为已经安排接收更新的网站需要取消优先级以腾出时间。

对不起,这太长了,但感谢任何帮助。我们越早进行一些更改以使我们有更好的发布时间表越好。谢谢!

【问题讨论】:

  • 您现在使用什么版本控制和自动构建系统?如果我理解正确,由于您要维护同一网站/应用程序的多个版本,因此您无法同时参加足够多的网站/应用程序,因此会出现延迟。对吗?
  • 我们使用组合的东西。我们使用名为 Vault 的产品进行版本控制,并使用名为 CC.NET (CruiseControl.Net) 的插件,它是一个持续集成/构建服务器,用于监控我们的存储库并生成构建。

标签: .net iis release-management sdlc


【解决方案1】:

事实证明,我在完全相同的环境中工作。以下是我们的系统设置:

  1. 每个客户端都有自己的数据库。实际上,您正在讨论多租户解决方案。虽然使用一个数据库来管理它们有其优势,但当您想要移动客户端或客户端想要托管自己的系统或版本之间存在架构差异(这很常见)时,就会出现问题。解决此问题的唯一其他方法是使用单个数据库,但按模式名称分段(例如 ClientA.Table1、ClientB.Table1...)。

  2. 我们使用单一代码库。我们使用虚拟目录来指向客户端正在使用的代码版本。同一构建上的所有客户端都指向相同的位。但是,我们可能在野外有多个版本。因此,一个客户端可能指向 1.0.0.0,而另一个客户端可能指向 1.0.1.1。

  3. 当我们想要更新某人时,我们将他们的虚拟目录指向请求的发布版本。物理文件夹以其完整的版本名称命名(即 1.0.3.4)。该应用程序旨在检测它期望的数据库版本和它拥有的数据库版本之间的差异。如果存在差异,它会重定向到管理员可以更新数据库模式的页面。所有数据库更改都是脚本化的,并且旨在以正确的顺序执行。我们使用版本号的第三个八位字节来表示数据库版本。所以 1.0.1.1 表示数据库架构是从 1.0.0.0 改变的。

  4. 可能会出现一个问题,“为什么要使用虚拟目录?”这涉及到开发的核心规则:应用程序代码不能包含任何客户端特定的数据或设置。具体来说,从应用程序文件夹的根目录向下的任何内容都不能是特定于客户端的。那么,连接字符串呢?这就是我们使用虚拟目录的原因。我们的虚拟设置如下所示:

clientsite (or vdir)
    /appname_vdir

客户端站点根文件夹包含一个 web.config 文件,其中包含任何非数据库驱动的客户端特定设置,例如连接字符串。当我们将/appname_vdir 指向新版本文件夹时,我们不必担心更新连接字符串或任何其他客户端特定数据。使这变得困难的是,每个更改都根据每个客户是否希望以相同的方式进行更改进行评估。如果没有,那么必须有一种方法来禁用(或不安装)该更改。

理想情况下,您希望托管尽可能多的客户端,因为您可以构建工具来自动化或控制将客户端指向更新版本并执行数据库更新的过程。

在某个时候,我们的计划是建立一种机制,让管理员收到新版本可用的通知。如果它们在我们的托管环境中,更新将涉及更改适当的虚拟目录路径。如果他们自己托管,它将提供一种下载位然后进行路径更改的方法。那部分我们还没有时间构建。此外,还可以构建一个管理工具,让支持人员更新人员并确定他们使用的版本。

【讨论】:

  • 哇,这听起来几乎和我们的环境一模一样。所以,我认为我的问题与您实际托管不同版本的方式有关。我相信我们会生成构建——在他们网站的当前版本之间做一个差异——并用新文件推送(覆盖)他们当前的网站。与此同时,我们运行适当的数据库脚本来更新数据库。完成这些步骤后,它们就处于“当前”版本中。您的解决方案改为使用虚拟目录。您认为我可以如何将其合并到我们的设置中?
  • @tresstylez - 我们通过拥有多个文件夹(以完整版本编号命名)来托管多个版本。两个不同的客户可能有他们的应用程序 vdir 指向不同的版本文件夹。如果两个客户端运行相同的构建,则它们的应用程序 vdir 指向相同的版本文件夹。
  • @tresstylez - 顺便说一句,它不一定是 vdirs;您可以在更新某人时更改站点的根文件夹。然而,这揭示了我们设置的另一个重要方面,即关于客户特定设置。我会修改我的回复以提供更多信息。
  • @Thomas - 因此,在进行了更多调查之后 - 他们一直在进行单独发布的主要原因之一是因为每个站点都使用自定义的 web.config 文件,其中主要包含与其数据库的连接字符串。此外,由于我们有 3 个不同的环境(QA、DEV、Production..),即使这些字符串也需要手动更新。此外,每个站点都有自己的配置文件,其中包括打开/关闭其站点上的功能的变量。您认为虚拟目录解决方案可以解决这些问题吗?
  • @Thomas - 另外,另一个曲线球可能是我们运行一个 .NET 应用程序 - 这包括我们 /bin 目录中的 dll 和 .aspx 文件.. dll、.aspx 文件和 web .config 是否存在于这个虚拟目录世界中?
【解决方案2】:

在我看来,你有两个选择:

  • 自己托管所有版本并智能区分客户端应该使用哪个版本
  • 让客户端自己托管应用程序

自己托管

我认为你可以这样做:

  • 安装当前使用的所有不同版本
  • 有一个域,每个客户端都有一个子域。客户端 ABC 登录 abc.mydomain.com 等。
  • 使用重定向或 URL 重写机制将它们静默重定向到您产品的适当版本
  • 当客户想要升级时,将他们的数据迁移到产品的后续实例,并更改他们的子域的重写规则

请注意,我在这里缺少一些细节,因为我对您的设置了解不多,例如每个客户都使用自己的数据库,还是您有多租户方法?他们是都使用产品的单独安装,还是使用相同的安装实例并只是获取不同的数据?

客户端托管

这可以相对简单地管理。您可以将应用程序的 ASP.NET 部分打包到 MSI 安装程序中,创建虚拟目录和应用程序池等都可以在 MSI 中完成。然后,您可以使用 DBGhost 之类的数据库升级工具来打包您的数据库——它将您的模板(源)数据库与目标数据库进行比较,然后生成使目标与源保持一致所需的 DDL。我知道其中一个版本的 VS2010 中还包含一个工具,但我没有使用它,无法评论它。


您的开发人员可以通过以易于使用的方式向支持团队提供更新来帮助减轻很多升级带来的痛苦。尽可能使用 MSI 软件包。尽可能使用工业级数据库创建/生成工具。如果由于某种原因您不能使用数据库升级工具,那么请确保以良好的方式编写数据库升级脚本(即 if object exists then alter else create)。如有必要,强制执行必须遵循的升级路径——如果客户端想要从 1.6 跳转到 2.0,那么他们必须先通过 1.8——这使得升级更加精细、可预测且易于管理(您维护 1.6 的升级脚本->1.8 和 1.8->2.0,您不必为 1.6->2.0 提供一个)。

我希望这能给您足够的思考 - 如果您有更多详细信息,请编辑您的帖子并添加它们。

【讨论】:

  • 感谢您的反馈。不幸的是,我们必须托管我们的网站和数据库,因为这些信息很敏感。你是什​​么意思'安装所有当前使用的版本'?这是否意味着您将每个版本都安装在 IIS 中自己的虚拟目录中?
  • @tres - 您是否对数据库进行了多租户(多个客户端使用相同的物理数据库,它们各自的信息由客户端 ID 标识)?还是为每个客户提供单独的数据库?如果您有多个运行产品 v2.0 的客户端,它们是否都运行相同的构建版本,还是存在细微差别?
  • 我们为每个客户端使用单独的数据库——它们的连接字符串在各自的 web.configs 中。如果多个客户端在 v.2.0 上,我相信代码是相同的。
【解决方案3】:

您是否考虑过自动执行应用程序的更新和部署。如果你能想出一个标准化的方式来打包应用程序,不管版本如何,使用 Nolio ASAP (http://www.noliosoft.com) 之类的工具将很容易实现自动化。这将使您能够为每个版本甚至每个帐户创建一个部署流程,并启用“几乎相同”的部署,其中可以输入差异作为每个部署的输入。

【讨论】:

    最近更新 更多