如何在一个Web应用程序中对版本控制不同的功能?

时间:2015-07-24 17:36:25

标签: php architecture system upgrade web-site-project

我们有一些网络应用程序,现在这些网站正在升级,而不是第一次,但是控制用户和开发人员的版本变得非常困难。

我们有很多客户,其中一些客户运行相同的应用程序,但他们需要支付升级费用。但是,并非所有客户都支付升级费用,因此我们有一些客户运行一个版本而另一个客户运行另一个版本。

我们有两种方式,我们正在研究第三种方式:

  1. 将版本放入路径中,如下所示:www\project\version\system-files
  2. 但是这种方式让一些用户感到困惑,因为对于他们来说,URL变为:www.website.com/app-version,并且当系统升级时,URL会发生变化。

    1. 将版本放入函数中,如下所示:function V1_functionX()
    2. 当需要升级函数时,我们创建一个名为V2_functionX的新函数。但是,这会产生一种“脂肪”#34;网站,团队在开发过程中犯了一些错误,因为我们没有"一个开发版本",但是"很多版本要开发",而且有些功能用于更多比一个网站。

      很久以前就放弃了第一种方式。我们开发了Web应用程序,"关闭了版本",并且所有请求都包含在升级版本中,完成时该版本已经关闭"太。但这太慢了太纠正和部署"小升级"

      我们谈到了另一家公司的方式:他们"关闭"网站升级系统。这可能是我们的方式。

      但是,如果有人有其他想法不关闭网站升级应用程序,我们将很乐意倾听。

      注意:这与SVN无关。

2 个答案:

答案 0 :(得分:0)

我的工作中有这个:

  1. 本地开发网站(SVN)
  2. dev服务器所有开发人员测试
  3. Preprod,一切都很好
  4. Prod(来自preprod的rsync)
  5. 2个服务器之间的rsync非常快,当我们在不到5秒内进行重大更新

答案 1 :(得分:0)

您说您必须为不同的客户维护不同版本的应用程序。我希望您不要告诉您这会大大增加整个系统的复杂性,因此您的首要任务是减少并行维护的版本数量。

API服务存在同样的问题:提供了具有更多功能的新版本,但需要维护旧版本以使新版本有时间稳定并为用户提供足够的时间来升级其代码。你的难度很相似。因此,我要问的第一个问题是,是否可以只保留两个版本。

如果无法做到这一点,请至少尝试最小化并发版本的数量:必须创建新版本,您需要鼓励用户从一个版本迁移到另一个版本。 (您已经说过无法将用户统一到一个版本,但如果没有关于您的确切用例的进一步信息,则无法提供独立的视图)。因此,也许一种方法是永远不要维持超过五个版本。

您可以采取多种策略来降低现有系统的复杂性。首先,考虑将您的代码分成一个"核心"所有版本绝对必须具备的功能。这对所有版本都是通用的,因此如果您在此处修复了错误,则所有客户都可以从修复程序中受益。这可能是一个可见的功能(例如产品编辑屏幕)或框架功能(例如在结账时强制使用SSL)。

您的核心库和特定于客户端的函数可以驻留在一组库中,如下所示:

/project/core
/project/versions/1/Class.php
/project/versions/1.1/Class.php
/project/versions/2/Class.php
/project/versions/2.1.1/Class.php
/project/versions/...

Class.php当然是一个例子 - 实际上这里会有很多类文件,每个都有适当的命名。)

通过这种方式,您不需要使用V1_前缀调用函数,因为这需要复制您的版本,在很多地方选择代码。加载与正确版本相关的库要好得多,只要所有版本的函数名都相同,你就可以使用函数名,你的库加载器将负责其余的工作。

另一种方法是使用插件,就像WordPress一样。添加插件时,它会通过添加新的或不同的行为来修改某些核心功能。 "中间件"设计模式在这里可能很有用 - Slim框架(毫无疑问是其他框架)使用这种方法将预调用或后调用挂钩添加到现有的路由处理程序,从而提供了一种干净的机制来编辑各种组合的现有功能。 / p>

总而言之,您当前的情况不仅仅是一个管理问题,而且还会花费您较慢的开发时间和额外的调试。虽然上述方法仍然有必要降低一些复杂性,但也要考虑:

  • 强制落后客户端升级到您当前支持的某个版本
  • 将落后客户端升级到最早可用的免费支持版本

基于新信息的一些额外想法。我是在思考是否将代码分成单独的存储库会有所帮助,每个客户端都有一个。但是我想知道他们是否会保证;即使您在使用Composer或Git子模块中提取核心功能,您的最新核心和最早的客户端代码之间仍可能出现分歧。在某些时候,你最糟糕的落后客户将阻碍核心发展。

你可以随时将这个客户端放在一个废弃的版本上,但是如果他们发现了一个bug,就不值得从你的最新核心后端移植一个修复程序,因为这会导致你遇到的所有兼容性问题。试图避免。要么他们升级到最新的客户端版本,使用最新的核心(并在必要时支付费用),或者他们无限期地容忍该错误。

您已经提到每个客户都有自己的数据库。这在某种程度上是有用的,因为它意味着客户端版本不完全受到核心强制的数据库模式决策的约束。但是,这仍然会对您可以移动到核心的代码数量产生连锁反应。

例如,假设您有七个客户端,其中六个拥有一个具有电子邮件地址的用户实体,以处理密码更改请求(一个客户端具有一个没有此字段的用户实体)。这意味着,如果笨拙的架构可能不会更改,则核心不能假定电子邮件地址可用。 (在这个简单的情况下,免费升级奇数输出可能会更便宜,因此更多的代码可以进入核心,而不是像标准版本那样保持标准的东西)。

考虑到复杂程度,而且听起来你长期保持这种状态,我认为你应该设置一些单元和功能测试。你需要将这些分成“核心”和#34;和#34;每个版本"同样。如果发现错误,无论是否由功能版本控制引起,请编写失败的测试,然后进行修复。然后,您将 - 至少在理论上 - 检查更改是否会以您未设想的方式影响特定客户端版本。