我有一个现有的Java EE 6应用程序(部署在Glassfish v 3.1中),并且希望支持多个租户。我目前在我的应用中使用的技术/ API是
据我所知,添加多租户支持仅影响持久层。我的问题:以前有人这样做过吗?转换应用程序的步骤是什么?这会影响除持久性以外的其他层吗?
将有大量租户,因此,所有数据都将驻留在同一个数据库架构中。
答案 0 :(得分:4)
从持久层开始。完成后,向上滚动您的架构。
您提议的架构将具有标识租户的ID(例如TenantId)。每个表都有此ID。在您的所有查询中,您必须确保TenantId与登录的用户的TenantId匹配。
这方面的困难在于它是一个非常手动的过程。
如果你使用Hibernate作为你的JPA提供者,那么有一些工具可以帮助解决这个问题。即 Hibernate Filters 。
这些通常用于限制多租户架构的访问权限(请参阅here和here for some more)
我没有使用过EclipseLink,但它看起来也像has good support for Multi-Tenancy。 DiscriminatorColumn看起来与Hibernate Filters非常相似。
我假设您正在将JAX-RS和JMS用于服务层。如果是这样,那么您还需要考虑如何通过租户和authenticate您的租户。您如何阻止一个租户访问另一个租户的REST服务? JMS也是如此。
您将不得不在UI中将您的登录信息连接到Bean(Hibernate或Eclipselink),以便为过滤器/鉴别器设置TenantId。
答案 1 :(得分:0)
告诉我们不同租户所需的分离和定制的数量和程度。
如果你有少量租户,我建议创建一个可定制的“白标”产品。这使您有机会为一个租户创建一些特定的东西而不会过度复杂。此外,将每个租户的应用程序分开可以帮助您进行维护。我们为少数不同租户的产品做了这个。
如果您有很多租户,这当然不再实用。我们做了相同产品的通用版本。我们所做的就是在登录后通过id区分租户,从而将数据与其他人分开。但是,在更改应用程序或其中的层方面没有任何关系,id是分离数据所需的全部内容,工作流通过具有bean或其他托管对象的不同实例自动分离。
答案 2 :(得分:0)
根据您希望实现的分离级别以及您希望支持的并发租户数量,您可以采用多种方式。在一个极端情况下,您可以为每个租户创建新架构,从而确保数据库级别的数据隔离。对于大多数实际用途,通过为域模型中的每个实体分配tenant_id
并维护外键约束,对数据进行逻辑分区通常就足够了。当然,这意味着您可能希望始终将当前会话的tenant_id
传递给每个查询/查找器方法,以便它可以基于此限制数据集。您需要通过在网址中输入不属于他们的租户ID(或实体ID)来确保用户无法访问其他租户的数据。
答案 3 :(得分:0)
以消息为导向。
如果您选择将消息传递作为战略方法并在JMS周围重构(如有必要)业务逻辑,那么其他选项仍然可行并且在本地适用。
通过这种方法,您可以在现有(单租户)系统中支付特定的固定成本(重构)。然后,您可以应用各种复杂程度的方法,从简单的分片(@ Geziefer的基于id的关联)到完整的共享核心模式+扩展租户特定模式方法,而不会影响系统架构和额外的重构。
您还可以通过消息传递层(应用路由器,过滤器,特殊处理路径等)对系统数据流进行正交控制。
[按要求编辑]
M.T.本身没有任何内容。明确建议消息方向。但作为一般问题,我们正在研究扩展接口和丰富数据流。根据基于API的方法,您需要在所有必需的接口(例如方法)中仔细注入适当的租户判别式。基于消息(或者基于上下文的API方法)允许规范(稳定)接口(例如,message.send())和同时允许显式专用数据流。如果不在桌面上切换到基于消息的主干,则强烈建议您考虑在API中注入统一上下文(例如“RequestContext”)参数。此单一扩展应涵盖您未来的所有专业化需求。