django上多租户应用的最优架构

时间:2011-08-25 17:01:46

标签: django architecture multi-tenant

我一直在思索创建多租户应用程序的正确/最佳方式 在Django上。

一些解释:

  • 应用程序可供多个租户使用(tenant1,tenant2,...,)。

  • 必须保护所有租户个人数据不被其他租户(及其用户)访问。

  • 可选租户可以为应用程序对象创建其他自定义字段。

  • 当然,底层硬件会限制一个“系统”上的租户数量。

1)将每个租户分开,例如子域和在底层使用特定于租户的数据库

2)在模型中使用一些租户ID来分离数据库中的租户数据

我在考虑部署过程,系统部件的性能(web-server(s),数据库服务器,工作节点......)

什么是最好的设置?专业人士和骗子在哪里?

您怎么看?

3 个答案:

答案 0 :(得分:54)

我们使用以下架构构建了多租户platform。我希望你能找到一些有用的提示。

  • 每个租户都有子域名(t1.example.com)
  • 使用url重写对Django应用程序的请求被重写为类似example.com/t1
  • 的内容
  • 所有网址定义都以(r'^(?P<tenant_id>[\w\-]+)
  • 为前缀
  • A middleware处理并使用tenant_id并将其添加到请求中(例如request.tenant ='t1')
  • 现在,您可以在每个视图中使用当前租户,而无需在每个视图中指定tenant_id参数
  • 在某些情况下,您没有可用的请求。我通过将tenant_id绑定到当前线程来解决此问题(类似于使用threading.local的{​​{3}})
  • 创建装饰器(例如租户识别login_required),中间件或工厂以保护视图并选择正确的模型
  • 关于数据库,我使用了两种不同的场景:
    • 根据当前租户设置多个数据库并配置current language。我首先使用了这个,但在大约一年后切换到一个数据库。原因如下:
      • 我们不需要高安全性的解决方案来分离数据
      • 不同的租户几乎使用了所有相同的模型
      • 我们必须管理很多数据库(并没有构建简单的更新/迁移过程)
    • 使用一个带有一些简单映射表的数据库,即用户和不同的模型。要添加其他特定于租户和租户的模型字段,我们使用routing

关于环境,我们使用以下设置:

从我的观点来看,这个设置有以下专业和概念:

临:

  • 了解当前租户的一个应用程序实例
  • 项目的大部分内容不必担心租户的具体问题
  • 在所有租户之间共享实体的简单解决方案(例如消息)

魂斗罗:

  • 一个非常大的数据库
  • 由于模型继承而导致的一些非常相似的表
  • 数据库图层不安全

当然,最佳架构在很大程度上取决于您对租户数量,模型的增量,安全要求等的要求。

更新:在我们审核我们的架构时,我建议重写URL,如第2-3点所示。我认为更好的解决方案是将tenant_id作为请求标头,并使用tenant_id之类的内容从请求中提取(第4点)request.META.get('TENANT_ID', None)。这样您就可以获得中性网址,并且使用Django内置函数(例如{% url ...%}reverse())或外部应用程序会更容易。

答案 1 :(得分:4)

以下是相关讨论的一些指示:

答案 2 :(得分:1)

我建议您查看https://github.com/bcarneiro/django-tenant-schemas。它会像Reto提到的那样解决你的问题,除了它使用postgresql模式。