SaaS /基于Java的Web应用程序(GWT,Spring,Hibernate)的多租户方法

2022-09-01 16:14:59

我目前正在考虑将一个基于Java的单租户Web应用程序转换为一个完全成熟的SaaS风格的应用程序,该应用程序使用Spring,GWT,Hibernate,Jackrabbit,Hibernate Search / Lucene(以及其他应用程序)。

我偶然发现了一篇文章,其中强调了以下7个“事情”,这是对单个租户应用进行的重要更改,以使其成为SaaS应用:

  1. 应用程序必须支持多租户。
  2. 应用程序必须具有某种级别的自助注册。
  3. 必须有订阅/计费机制。
  4. 应用程序必须能够有效地扩展。
  5. 必须有适当的功能来监视、配置和管理应用程序和租户。
  6. 必须有适当的机制来支持唯一的用户标识和身份验证。
  7. 必须有适当的机制来支持每个租户的某种程度的自定义。

我的问题是,是否有人使用与我列出的技术类似的技术在SaaS / 多租户应用程序中实现了上述7件事中的任何一种?在我走上我目前正在考虑的道路之前,我渴望获得尽可能多的关于最佳方法的意见。

首先,我很确定我对如何在模型级别处理多个租户有很好的把握。我正在考虑向所有表添加租户 ID,然后使用休眠筛选器(以及用于休眠搜索的全文筛选器)根据登录用户的租户 ID 对所有查询进行筛选。

然而,我对性能也有一些担忧,特别是当我们的租户数量增长相当高时。

关于如何实现这种解决方案的任何建议将不胜感激(如果这个问题有点过于开放,我很抱歉)。


答案 1

我建议你构建应用程序以支持所有 4 种类型的租户隔离,即每个租户的单独数据库、每个租户的单独架构、每个租户的单独表以及具有租户 ID 的所有租户的共享表。这将使您可以灵活地随着数据库的增长而对数据库进行水平分区,使多个数据库具有一组较小的租户,并且还能够为某些大型租户提供单独的数据库。一些大型租户也可能坚持认为他们的数据(数据库)应该驻留在他们的前提中,而应用程序可以在云中运行。

以下是您在构建应用程序时可能要考虑的非功能和基础架构级别功能的专门检查列表(其中一些您可能不需要立即使用,但请考虑一下业务情况,即如果您的竞争对手开始提供这种需求,您将如何处理这种需求)

  1. 租户级别自定义 a) UI 主题和徽标 b) 表单和网格,c) 数据模型扩展和自定义字段,d) 通知模板,e) 拾取列表和主数据
  2. 角色和特权、字段级访问权限、数据范围策略的租户级创建和管理
  3. 模块和功能的租户级访问控制设置,以便可以根据订阅包启用/禁用特定模块和功能。
  4. 任务/事件/事务的计量和监控,以及超过购买配额后访问控制的限制。如果您的业务模式发生变化,能够在未来对任何新实体进行计量。
  5. 将业务规则和工作流外部化到代码库中,并将它们表示为元数据,以便可以为每个租户组/租户自定义它们。
  6. 查询生成器,用于创建可识别租户的自定义报表以及特定租户添加的自定义字段。
  7. 租户封装和框架级连接字符串管理,以便开发人员在编写查询时不必担心租户 ID。

所有这些都基于我们在构建可用于任何域或应用程序的通用多租户框架方面的经验。不幸的是,您不能使用我们的框架,因为它基于.NET。

但是,无论您使用哪种技术堆栈,任何多租户 SaaS 产品(新的或迁移的)的工程需求都是相同的。


答案 2

您列出的所有技术对于单租户和多租户应用程序都非常普遍和合理。我想说的是,支持SaaS的7个“事情”更多地取决于你如何使用这些技术。听起来您已经有一个可以正常工作的单租户应用程序。因此,可能没有太多理由偏离那里的技术选择,除非某些事情已经不能很好地工作。你的问题在其他方面是相当开放的,所以很难在那里更具体。

不过,我确实有一些关于按租户ID拆分数据库(也许还有其他东西)的反馈。如果您知道自己最终可能会有很多租户(例如数千个或更多,特别是如果它们很小),那么您的建议可能是最好的。但是,如果租户数量较少(特别是如果它们很大),则可能需要考虑每个租户一个数据库,以便它们各自拥有自己的表空间。我的意思是单个数据库安装,其中包含同一架构的多个实例,每个租户一个。

有几个原因可能是一个优势。一个是你提到的性能。向每个表添加租户 ID 会在磁盘访问、查询时间方面产生开销,并会增加代码复杂性。数据库中的每个索引也需要包含租户 ID。如果不小心,则会面临在租户之间混合数据的额外风险(尽管 Hibernate 筛选器有助于缓解这种情况)。对于每个租户的数据库,可以将访问权限限制为仅正确的数据库。移植当前应用程序可能也要容易得多,您基本上只需要在某个地方提前拦截您的请求,即可根据URL确定租户并指向正确的数据库。每个租户也很容易进行备份,如果您打算允许他们下载备份,则特别有用。

另一方面,有理由不这样做。你将有很多数据库架构需要处理,并且它们必须独立更新(如果要避免因架构更改而关闭所有租户,这实际上是一个优势,你可以增量方式推出它们)。它使你有特殊情况,这些情况可能会偏离将平台视为真正的多租户SaaS部署,该部署一次升级,从而导致在生产中管理多个版本。最后,我听说几乎每个数据库供应商在一次安装中支持的模式实例数量(据说有些可以达到数十万个)都有一个突破点。

当然,这实际上取决于您的用例。你提到了单租户,这让我相信你现在没有太多的租户,但是你确实提到了增长到很多租户。我不确定你的意思是数亿还是数百万,但无论哪种方式,我希望这有助于你的考虑。祝你好运!


推荐