27

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

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

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

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

首先,我很确定我对如何在模型级别处理多个租户有很好的了解。我正在考虑将租户 ID 添加到我们所有的表中,然后使用 Hibernate 过滤器(以及用于 Hibernate 搜索的全文过滤器)根据登录用户的所有查询的租户 ID 进行过滤。

然而,我确实对性能有一些担忧,尤其是当我们的租户数量增长得相当高时。

任何有关如何实施此类解决方案的建议将不胜感激(如果这个问题有点过于开放,我深表歉意)。

4

5 回答 5

14

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

这是您在构建应用程序时可能需要考虑的非功能和基础架构级别功能的详尽清单(其中一些您可能不会立即需要,但请考虑一下业务情况,如果您的竞争开始提供它)

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

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

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

于 2011-04-19T10:26:51.967 回答
4

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

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

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

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

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

于 2011-03-30T03:57:44.030 回答
0

对于 (1):Hibernate 从版本 4 开始支持开箱即用的多租户配置。在撰写本文时,支持的是 DB-per-tenant 和 schema-per-tenant,并且尚未使用鉴别器将所有租户保持在同一个 DB 中支持的。我们已经在我们的应用程序中成功地使用了这个功能(DB-per-client 方法)。

对于(3):经过一些调查,我们决定与 Braintree 一起实施计费。许多人推荐的另一种解决方案:Authorize.net、Stripe、PayPal。

对于 (4):我们使用 Hibernate/Spring 和 JBoss Cache 的集群配置进行二级缓存。在这些日子里,这变得“普遍”,使用 Jelastic 等 PaaS 服务,您甚至可以开箱即用地对其进行预配置。

于 2012-04-16T17:26:54.430 回答
0

没有简单的答案。我可以描述我自己的解决方案。它可以作为其他人的灵感。

  • 每个数据库的租户(postgres)
  • 租户之间共享一个额外的数据库
  • Spring + MyBatis
  • Spring Security 身份验证

详细信息:http: //blog.trixi.cz/2012/01/multitenancy-using-spring-and-postgresql/

于 2012-01-29T17:55:40.213 回答
0

您所描述的是一个服务于多个租户的全方位服务的 Saas 风格应用程序。您必须决定一些事情,例如数据隔离有多重要?如果您正在为医疗或金融领域构建,数据隔离是一个关键因素。

好吧,我无法回答您的所有观点,但我建议您为您的应用程序查看每个租户的数据库方法,因为它提供了最高级别的数据隔离。

由于您使用的是 Java、Spring、Hibernate 堆栈,因此我可以通过我编写的一个小示例应用程序来帮助您。这是一个可以在本地笔记本电脑上快速运行的工作示例。我已经在这里分享了。请看一下,如果它回答了您的一些问题,请告诉我。

于 2018-04-12T18:51:48.530 回答