然而,问题是这个应用程序将拥有大量租户(5,000-10,000),拥有大量用户,单个租户可能有2,000个.我们需要每周支持几个租户增加系统.
此外,所有租户及其用户将被呈现一个共同的登录过程(即每个租户不能拥有自己的URL).为此,我需要一个集中登录过程和一种动态添加数据库到系统并注册用户的方法.
>如何稳健地自动注册和数据库创建过程?
>在系统上创建和注册租户数据库的过程是否可能导致性能或锁定问题.如果您认为这可能是个问题,那么有人可以建议减轻它的方法吗?
>我如何以用户凭证与特定租户的数据库相关联的方式管理中央身份验证,但用户可以通过公共页面登录(即通过相同的登录URL,但他们的主应用程序将在某些特定的租户上)数据库).租户必须能够维护自己的登录和权限,但中央登录系统必须了解这些.有谁能建议这样做的方法?
>如果我需要通过添加多个数据库服务器来“扩展”,那么有人可以建议我在管理服务器上的用户身份(模仿等)时可能需要处理哪些问题以及某些方法来缓解这些问题?
解决方法
CREATE TABLE dbo.Instances ( InstanceID INT PRIMARY KEY,Connection VARCHAR(255) --,... ); INSERT dbo.Instances SELECT 1,'PROD1\Instance1'; INSERT dbo.Instances SELECT 1,'PROD2\Instance1'; -- ... CREATE TABLE dbo.Tenants ( TenantID INT PRIMARY KEY,Name NVARCHAR(255) NOT NULL UNIQUE,InstanceID INT -- Foreign key tells which instance this tenant's DB is on --,... ); INSERT dbo.Tenants SELECT 1,'MyTenant',1; -- ... CREATE TABLE dbo.Users ( UserID INT PRIMARY KEY,Username VARCHAR(320) NOT NULL UNIQUE,PasswordHash VARBINARY(64),-- because you never store plain text,right? TenantID INT -- foreign key --,... ); INSERT dbo.Users SELECT 1,'foo@bar.com',0x43...,1;
在我们添加新租户的情况下,我们将动态构建数据库,但是当管理员用户在UI中单击OK时…我们有一个后台作业,每隔5分钟将新数据库从队列中拉出来,将模型设置为single_user,然后按顺序创建每个新数据库.我们这样做是为了(a)阻止管理员用户等待数据库创建,以及(b)避免两个管理员用户同时尝试创建数据库或以其他方式拒绝锁定模型的能力(创建新数据库时需要) ).
使用名称Tenant000000xx创建数据库,其中xx表示Tenants.TenantID.这使维护工作变得非常容易,而不是拥有名为BurgerKing,McDonalds,KFC等的各种数据库.并不是说我们只是以快餐为例,只是以此为例.
我们没有预先分配数千个数据库作为评论建议的原因是我们的管理员用户通常知道租户会变得多大,他们是否具有高优先级等等.所以他们在UI中有基本的选择.将决定他们的初始大小和自动增长设置,他们的数据/日志文件将进入哪个磁盘子系统,他们的恢复设置,铰接的备份计划,甚至是关于将数据库部署到哪个实例的智能,以便最佳地平衡使用(虽然我们的管理员可以覆盖这个).创建数据库后,使用所选实例更新租户表,为租户创建管理员用户,并通过电子邮件将我们的管理员通过电子邮件传递给新租户.
如果您使用单一入口点,则允许多个租户拥有相同用户名的用户是不可行的.我们选择使用电子邮件地址 – 如果所有用户都为公司工作并使用他们的公司电子邮件地址 – 应该没问题.虽然我们的解决方案最终变得更加复杂,原因有二
>我们的顾问服务于多个客户,并且需要访问多个客户
>我们的租户本身实际上是由多个租户组成的
因此,我们最终得到了一个TenantUsers表,允许一个用户与多个租户相关联.
最初,当用户登录时,应用程序将仅知道控制数据库的连接字符串.登录成功后,它可以根据找到的信息构建连接字符串.例如.
SELECT i.Connection FROM dbo.Instances AS i INNER JOIN dbo.Tenants AS t ON i.InstanceID = t.InstanceID INNER JOIN dbo.TenantUsers AS u ON i.TenantID = u.TenantID WHERE u.UserID = @UserID;
现在,应用程序可以连接到用户的数据库(每个用户都有默认租户),或者用户可以从他们可以访问的任何租户中进行选择.然后,应用程序将只检索新的连接字符串,并重定向到该租户的主页.
如果你进入你建议的这个10MM用户区域,你肯定需要更好地平衡这个.您可能希望联合应用程序,以便它们具有连接到不同控制数据库的不同入口点.如果您为每个租户提供一个子域(例如TenantName.YourApplicationDomain.com),那么您可以在DNS /路由的幕后进行此操作,而无需在需要进一步扩展时将其中断.
还有很多东西 – 比如@Darin我只是在这里搔痒.如果您需要非免费咨询,请告诉我.