为成熟的企业应用程序实施多租户
Posted
技术标签:
【中文标题】为成熟的企业应用程序实施多租户【英文标题】:Implementing multi-tenancy for a mature enterprise application 【发布时间】:2011-11-24 11:16:16 【问题描述】:我的任务是制作一个企业应用程序多租户。它有一个使用 SOAP Web 服务和 PostgreSQL 后端的 Java/Glassfish BLL。每个租户都有自己的数据库,因此(至少在我的情况下)“多租户”意味着每个应用服务器支持多个数据库。
当前的单租户应用服务器使用从配置文件中获取的连接字符串初始化 C3P0 连接池。我的想法是,现在应用服务器服务的每个客户端/数据库都需要一个连接池。
一旦用户登录,我可以通过查找其租户将其映射到正确的连接池。我的主要问题是如何做到这一点 - 当用户首次登录时,会查询后端的 User
表并提供相应的 User
对象。看来我需要知道使用哪个数据库,只有一个用户名才能使用。
我唯一不错的想法是需要一个“配置”数据库——一个用于管理租户信息(如连接字符串)的集中式数据库。 BLL 可以查询该数据库以获得足够的信息来初始化必要的连接池。但由于我只有一个用户名可以使用,看来我还需要一个集中的用户名查找,换句话说,一个带有 Tenant
表外键的 UserName
表。
这就是我的设计计划开始发臭的地方,这让我产生了疑问。现在我将在两个单独的数据库中拥有用户信息,这需要同步维护(用户添加、更新和删除)。此外,用户名现在必须是全球唯一的,而之前它们只需要每个租户都是唯一的。
我强烈怀疑我正在重新发明***,或者至少有更好的架构可能。我以前从未做过这种事情,我的团队中也没有任何人,因此我们无知。不幸的是,该应用程序很少使用现有技术(例如,ORM 是自制的),因此我们的道路可能会很艰难。
我要求以下内容:
对我现有设计计划的批评,以及改进或改造架构的建议。 提供解决此问题的现有技术的建议。我希望可以在游戏后期轻松插入的东西,尽管这可能是不现实的。我已经阅读了有关 jspirit 的信息,但几乎没有找到关于它的信息 - 任何关于它或其他框架的反馈都会有所帮助。更新:该解决方案已成功实施和部署,并已通过初步测试。感谢@mikera 的帮助和令人放心的回答!
【问题讨论】:
【参考方案1】:一些快速的想法:
您肯定需要某种形式的共享用户管理索引(否则您无法将客户端登录名与正确的目标数据库实例相关联)。但是我建议让这个非常轻量级,并且只将它用于初始登录。一旦您确定这是哪个数据库,您的 User 对象仍然可以从特定于客户端的数据库中提取。 您可以设置主键 [clientID, username],这样用户名就不需要在客户端之间保持唯一。 除了这个瘦用户索引层之外,我会将大部分用户信息保留在客户端特定数据库中的位置。现在重构它可能会造成太大的破坏,您应该先让基本的多租户功能正常工作。 您需要保持共享索引与各个客户端数据库同步。但我认为这应该不会太难。您还可以使用批处理作业“测试”同步并纠正任何错误,批处理作业可以在一夜之间运行,如果有任何不同步的情况,也可以由您的 DBA 按需运行。我会将客户端数据库视为主数据库,并使用它来按需重建共享用户索引。 随着时间的推移,您可以重构向完全共享的用户管理层(如果您愿意,甚至最终完全共享的客户端数据库。但将其保存以备将来迭代.....【讨论】:
+1 这个答案让人放心。配置数据库将非常轻巧-正如您所说,仅在连接池初始化和用户名查找期间使用。关于每晚清理/报告松散端的批处理作业的优点。以上是关于为成熟的企业应用程序实施多租户的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot - 多租户 - 优化 API 的响应时间