一个应用程序多个实例和不同的DB

Mik*_*iaz 7 sql asp.net-mvc database-connection multi-tenant

我正在构建一个案例管理应用程序,其中一个要求是每个客户端使用自己的URL获取自己的数据库.但是,升级时维护应用程序的多个实例已成为一场噩梦.我正在使用IIS 7 ASP.NET MVC.我想有一个应用程序,让应用程序知道根据用户身份验证从哪个数据库获取数据.有可行的替代方案吗?

Ada*_*hah 11

是的,如果可能的话,最好有一个应用程序实例,否则会变得复杂.如果不同客户端的功能不同,则使用功能标志为每个客户端/用户打开/关闭功能.请参阅Martin Fowler的以下文章.功能标志可以是每个用户或客户端.Facebook和其他几个主要网站都有效地使用功能标记.

http://martinfowler.com/bliki/FeatureToggle.html

关于数据库,我认为你可以有一个Common数据库,它包含所有基本信息,包括所有客户端,然后有特定于每个客户端的其他数据库,其中包含客户端的所有其他数据.

当任何用户在Global.asaxSession_Start方法中命中客户端特定URL时,添加逻辑以获取相应的连接字符串并将其存储在session()中,以便您可以在需要来自客户端数据库的数据时使用它.Session["ClientDbConnectionString"]

我建议您将所有连接字符串存储在Common数据库的表中(使用标识每个客户端的键),以便在您希望加载新客户端时添加新的连接字符串行.每当您执行新版本时,我建议一起更新所有客户端数据库,而不是仅更新一个客户端数据库,否则一段时间后它将变得无法管理.


Rem*_*anu 9

你的问题实际上只是一个冰山一角的问题.多租户是一个复杂的主题.与租户数据库建立每个客户端连接只是一个方面.还有其他方面需要考虑:

  • 租户平衡:您如何确保比平均增长速度快得多的租户获得足够的资源,并且不会压倒在同一存储器上并置的其他租户(例如同一个实例).你如何移动已经成长的租户?你如何汇总低活动的小租户?
  • 资源隔离:租户可以消耗大量资源(例如,它可以在数据库中运行查询,占用所有CPU并使所有其他查询匮乏),您如何确保其他租户的公平性?
  • 共享数据.复制对共享数据的更改(所有租户中常见的数据,例如查找表)可能会有问题.
  • 架构更改.这是最棘手的话题之一.数据库模式和代码通常是同步更改的(代码需要某个模式),并且对所有租户部署模式更改可能会有问题.

我建议你阅读多租户数据架构白皮书.这提出了三种基本方法:

另外,我会添加SQL Azure Federations选项(在编写白皮书时不可用).本文从数据库/存储的角度讨论了这些方法的优缺点,考虑如下:

  • 存储成本
  • 安全
  • 可用性
  • 可扩展性
  • 易于架构更改(应用程序升级)
  • 可扩展性

从客户端来看,我不知道任何有助于多租户案例的MVC扩展,这与Rails 中的act_as_tenant gem一致.

在升级时维护应用程序的多个实例开始成为一场噩梦.

这实际上是多租户架构中最大的问题之一.即使你已经消除了在DB中实际升级的摩擦,它仍然是一个难以解决的问题.除非您能够承担所有租户的停机时间并使整个系统脱机,升级所有租户数据库,部署了解新架构的新代码,然后将所有租户联机,因为应用程序代码(ASP/MVC代码)在线执行是很有挑战性的必须能够同时理解这两个版本(旧的和新的).不是不可能解决,但很难并且必须仔细编码.

话虽如此,如果"消除实际升级的摩擦",这是一个重要的部分.我没有采用什么程序来部署升级.至关重要的是,升级是自动化和脚本化的,无需任何手动干预.有时会使用基于Diff的工具,例如Red-Gate的SQL Compare甚至Visual Studio vsdbcmd.exe.我最喜欢的方法是在应用程序中使用升级脚本和元数据版本控制.有关详细信息,请参阅版本控制和数据库.作为参考,这种方法基本上是Rails迁移方法.