我正在构建一个多租户 ASP .NET 应用程序。鉴于每个租户都可以动态配置其应用程序(这可能涉及将动态自定义程序集加载到内存中),我需要一种隔离每个租户的方法。
出于维护原因,我不想为每个租户创建新的 Web 应用程序。
我一直在考虑使用 AppDomainManager 为每个应用程序创建一个 AppDomain,但似乎这并不打算用于 ASP .NET 应用程序。
有人对此主题有一些建议吗?
谢谢。
我想问题是:如果您不喜欢创建 Web 应用程序,那么什么类型的隔离是您真正可以接受的?
如果您确实想要一种操作系统级别的保证,即程序集不会相互干扰,我会给每个程序集提供自己的 Web 应用程序。如果您允许人们加载第三方程序集,则尤其如此,如果这些第三方程序集可以找到实例化非托管代码的方法,则尤其如此。
我认为,如果所有(托管)代码都是您的,则不需要创建单独的 Web 应用程序,但是一旦您将动态自定义程序集放入其中,我认为这是唯一的方法。
当您创建不同的网站时,您的 URL 根目录肯定会发生变化。我在想为什么不在主应用程序中使用不同的应用程序,并根据需要将它们放入不同的应用程序池中?
一个...这样,根 URL 将保持不变。 二...创建 VDir 或应用程序的实例。哪一项需要动态? 三...我没有专业知识。
如果我必须共享页面,[基于不同 VDir 中托管的应用程序],我会为所有共享页面创建一个新的 VDir。并使用一些自定义代码来显示应用程序相关数据。
我用 MVC2 编写了多租户 Web 应用程序。添加/删除帐户与添加/删除表中的行一样复杂,因为我选择了共享数据库、共享模式方法。
这是一篇来自 MSDN 的关于多租户数据库设计的非常好的文章:多租户数据架构
我在 MVC 中要做的就是正确设置路由,因此路径的第一部分是帐户名:
我有一个自定义的 MvcHandler 用于查找每个请求的帐户:
public class AccountMvcHandler : MvcHandler
{
public AccountModel Account { get; set; }
public AccountMvcHandler(RequestContext requestContext)
: base(requestContext)
{
}
protected override IAsyncResult BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, object state)
{
string accountName = this.RequestContext.RouteData.GetRequiredString("account");
Account = ServiceFactory.GetService<IAccountService>().GetAccount(accountName);
// URL doesn't contain valid account name - redirect to login page with Account Name textbox
if (Account == null)
httpContext.Response.Redirect(FormsAuthentication.LoginUrl);
return base.BeginProcessRequest(httpContext, callback, state);
}
}
正如 Andreas Paulsson 所说,关键词是“自定义组件”。为什么需要“自定义程序集”进行配置?您使用 CodeEmit 吗?用户会上传它们吗?我宁愿考虑使用 Windows Workflow Foundation 进行任何特定于客户端的业务逻辑自定义。
多租户架构有许多不同的方法。这取决于您的要求,但根据我的经验,大多数公司更喜欢从可以托管多个租户的单个数据库和单个应用程序开始,然后从那里开始。看来这种方法也应该适合你。
这种方法的好处是实施起来不太难,并且可以节省大量资金,这对于必须向客户提供 SaaS 解决方案并争夺定价的公司来说尤其重要。
它的工作方式基本上是,您只需将所有应支持多租户复合键的表主键设置为由 TenantId 和 Id 列组成。 TenantId 可以而且通常也是引用 Tenants 表的外键。租户表是您定义租户的位置。要添加新租户,您只需在租户表中添加一条新记录,您可以通过构建一个管理模块来使其变得非常简单,在该模块中应用程序管理员可以使用 UI 配置新租户,而无需为每个租户进行新部署租户。
这里有一篇文章,详细介绍了如何实现此架构:https://developerpartners.com/blog/f/multi-tenant-saas-architecture-with-entity-framework-core
关于与动态加载自定义程序集相关的部分,您可以添加一个名为 TenantFeatures 的表,并使用该表来确定每个租户使用哪些程序集(功能)。 TenantFeatures 表只能包含 TenantId 和功能名称,我想这些功能可以表示为管理页面中用于管理租户的复选框。