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

Oli*_*urg 61 architecture django multi-tenant

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

一些解释:

  • 应用程序可以由几个租户使用(tenant1,tenant2,...,).

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

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

  • 当然,底层硬件限制了一个"系统"上的租户数量.

1)通过例如子域和在底层中使用特定于租户的数据库来分离每个租户

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

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

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

你怎么看?

Ret*_*old 56

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

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

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

从我的角度来看,这个设置有以下专业版和内容:

优点:

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

魂斗罗:

  • 一个相当大的数据库
  • 由于模型继承,一些非常相似的表
  • 在数据库层上没有安全保护

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

更新:在我们审核我们的架构时,我建议不要重写URL,如第2-3点所示.我认为一个更好的解决方案是把tenant_id作为请求头,并提取(4点)的tenant_id出请求的喜欢的东西request.META.get('TENANT_ID', None).通过这种方式,您可以获得中性URL,并且使用Django内置函数(例如{% url ...%}reverse())或外部应用程序会更容易.

  • 然后我建议你使用带有自动路由的多数据库设置.我会使用[south](http://south.aeracode.org/)管理数据库,因为它们现在支持多个数据库. (2认同)