我们为特定的利基行业编写了一个软件包。这个软件包非常成功,我们已经注册了业内几个不同的客户,他们使用我们作为托管解决方案提供商,还有许多人正在敲门。如果我们实现了我们的目标,我们将拥有数百个客户,每个客户都有自己的网站托管在我们的服务器上。
麻烦的是,每个客户都会根据当地的州或甚至县立法或官僚机构,根据自己的当地情况和条件进行自己的小定制和调整,这些情况经常(但并非总是如此)。因此,虽然可能90-95%的系统在所有客户端都是相同的,但我们将不得不构建并支持这些小的自定义。
此外,该系统仍在进行中。在核心系统上不断发生需要应用于所有客户端的增强功能和错误修复。
我们用.NET编写代码(ASP,C#),MS-SQL 2005是我们的数据库服务器,我们使用SourceGear Vault作为源代码控制系统。我之前曾在Vault中使用分支,如果你只需要保持2个或3个分支同步,那就太棒了 - 但我们正在考虑维护数百个分支,这是不可想象的。
我的问题是:您如何建议我们管理所有这些?
我希望答案能够解决对象架构,Web服务器架构,源代码管理,开发团队等问题。我有一些自己的想法,但我没有管理类似这样的事情的真实经验,而且我我非常感谢之前做过这类事情的人的听证会。
谢谢!
答案 0 :(得分:21)
我建议反对为每个客户维护单独的代码分支 。这对于维护Core的工作代码来说是一场噩梦。
我建议您在更换Core时使用自动化测试(例如Unit& Functional)实施Strategy Pattern并覆盖“客户自定义”。
<强>更新强>
我建议您在太多客户之前,需要建立一个创建和更新每个网站的系统。您当中的参与程度当然会受到当前收入流的影响,但您应该牢记这一点。
例如,当您刚刚注册客户X(希望通过网络全部注册)时,他们的网站将在XX分钟内创建,并向客户发送一封电子邮件,说明它已准备就绪。
您肯定想要设置持续集成(CI)环境。 TeamCity是一个很棒的工具,而且是免费的。
有了这个,您就可以在暂存环境中检查更新,然后可以在生产实例中应用这些补丁。
底线:一旦您了解了少数客户,您就需要开始考虑将自己的运营和部署自动化为另一个应用程序。
更新:post突出了每位客户分支的负面影响。
答案 1 :(得分:10)
这不是您希望通过源代码管理来解决的问题,而是在应用程序的体系结构中。
我想出一些类似于架构的插件。哪个插件用于哪个网站会成为配置问题,而不是源控制问题。
这允许您使用分支等来处理它们的目的:在(甚至可能甚至更多)版本之间并行开发代码。每个插件都成为源代码系统中的单独项目(或子项目)。这也允许您将所有插件和主应用程序组合到一个visual studio解决方案中,以帮助进行依赖性分析等。
在应用程序中松散耦合各种组件是最好的方法。
答案 2 :(得分:10)
我们的软件有非常相似的要求,多年来我已经做了一些事情。
首先,此类自定义将在短期和长期内使您付出代价。如果您可以控制它,请进行一些检查和平衡,以便销售和销售。营销不要过度热销自定义。
我同意其他海报说不使用源代码管理来管理它。应尽可能将其内置到项目体系结构中。当我第一次开始为我现在的雇主工作时,源控制正在被用于此,它很快成为一场噩梦。
我们为每个客户使用单独的数据库,主要是因为对于我们的许多客户而言,由于隐私问题等原因,法律或客户本身都需要它...
我想说,业务逻辑差异可能是我们体验中最不困难的部分(您的里程可能因所需定制的性质而异)。对我们来说,业务逻辑中的大多数变体可以分解为一组配置值,我们将这些配置值存储在xml文件中,该文件在部署时修改(如果是特定于机器的)或存储在客户端特定的文件夹中并保存在源代码管理中(解释)下面)。业务逻辑在运行时获取这些值并适当地调整其执行。您可以将其与各种策略和工厂模式一起使用 - 配置字段可以包含策略名称等....此外,单元测试可用于验证您在进行更改时没有为其他客户端破坏内容。目前,向系统添加大多数新客户端只需简单地混合/匹配适当的配置值(就业务逻辑而言)。
对我们来说,更多的问题是管理网站本身的内容,包括页面/样式表/文本字符串/图像,所有这些都是我们的客户经常需要定制的。我为此采取的当前方法是为镜像主站点的每个客户端创建一个文件夹树 - 该树根植于名为“custom”的文件夹,该文件夹位于主站点文件夹中并随站点一起部署。放置在特定于客户端的文件夹集中的内容将覆盖默认内容或与默认内容合并(取决于文件类型)。在运行时,根据当前上下文(用户,语言等)选择正确的文件。该网站可以通过这种方式为多个客户提供服务。效率也可能是一个问题 - 您可以使用缓存等...使其更快(我使用自定义VirtualPathProvider)。我们遇到的最大问题是当我们需要进行更改时,可视化测试所有这些页面的负担。基本上,当您更改共享样式表,图像等时,100%确定您没有在客户端的自定义设置中破坏某些内容......您必须在任何重大设计更改后直观地检查每个页面。随着时间的推移,我已经形成了一种“感觉”,即在不破坏事物的情况下可以轻松地进行哪些改变,但它无论如何仍然不是一个万无一失的系统。
在我的情况下,除了提供我对哪些视觉/代码定制销售的看法之外,我也没有任何控制权,因此我们想要销售和实施的内容多得多。
答案 3 :(得分:2)
如前所述,源代码管理听起来不是解决问题的好方法。对我来说,听起来更好,你有一个使用多租户架构的单一代码库。通过这种方式,您可以在管理应用程序,加载服务,扩展性等方面获得很多好处。
我们使用这种方法的产品和我们拥有的是一些(大量)核心功能,对于所有客户来说都是相同的,一个或多个客户使用的自定义模块以及“自定义”的核心是简单的工作流引擎,为不同的客户端使用不同的工作流,因此每个客户端都获得核心功能,自己的工作流和一些扩展的模块集,这些模块可以是特定于客户端的,也可以是针对一个客户端的一般化。
这是让您开始使用多租户架构的一些方法:
答案 4 :(得分:1)
如果没有更多信息,例如客户特定的自定义类型,人们只能猜测更改的深度或肤浅程度。一些简单/标准的方法需要考虑:
基于客户端名称/ ID的整体硬编码差异是非常有问题的,每个客户端保持不同的代码库是昂贵的(想想90%不需要更改所需的完整测试/重新测试时间)...我认为需要更多信息才能正确回答(提供一些细节)
答案 5 :(得分:0)
分层应用程序。其中一个层包含自定义,应该可以随时拉出,而不会影响系统的其余部分。应用程序和数据库级“触发器”(引用,因为它们可能或许多不使用实际的数据库触发器)调用客户特定代码或使用客户密钥进行参数化非常有用。
Core永远不应该自定义,但你必须在某个地方将其分层,即使它是简单的Web过滤。
答案 6 :(得分:0)
我们拥有的核心数据库具有所有客户端获得的功能。然后每个客户端都有一个单独的数据库,其中包含该客户端的自定义项。这在维护方面是昂贵的。另一个问题是,当两个客户要求同时使用simliar功能时,两个独立的团队通常会做出不同的决定。目前很少有人在客户端之间共享custiomization,并使常见的成为核心应用程序的一部分。每个客户端都有自己的应用程序门户,因此我们不必担心一个客户端的更改会影响其他客户端。
目前我们正在考虑使用规则引擎更改为流程,但有些人担心我们需要能够处理的记录数量不会达到性能。但是,在您的情况下,这可能是一个可行的替代方案。
答案 7 :(得分:0)
我使用了一些提供以下自定义功能的应用程序:
如果您的客户是大公司,那么您几乎需要自己的SDK,API等。