我一直在思考创建基于 Multi-Tenancy 应用程序的正确/最佳方式 在 Django 上。
一些解释:
多个租户(租户 1、租户 2、...)可以使用应用程序。
必须保护所有租户个人数据,防止其他租户(及其用户)访问。
租户可以选择为应用程序对象创建额外的自定义字段。
当然,底层硬件限制了一个“系统”上的租户数量。
1) 通过例如分隔每个租户子域并在底层使用特定于租户的数据库
2) 在模型中使用一些tenant-ID来分离数据库中的tenant-data
我正在考虑部署流程、系统部件(网络服务器、数据库服务器、工作节点……)的性能
最好的设置是什么?优缺点在哪里?
你怎么看?
最佳答案
我们构建了一个 Multi-Tenancy platform使用以下架构。我希望您能找到一些有用的提示。
- 每个租户都有子域(t1.example.com)
- 使用 url 重写 Django 应用程序的请求被重写为类似 example.com/t1 的内容
- 所有 url 定义都带有类似
(r'^(?P<tenant_id>[\w\-]+)
的前缀 - A middleware处理并使用 tenant_id 并将其添加到请求中(例如 request.tenant = 't1')
- 现在您在每个 View 中都有可用的当前租户,而无需在每个 View 中指定 tenant_id 参数
- 在某些情况下,您没有可用的请求。我通过将 tenant_id 绑定(bind)到当前线程解决了这个问题(类似于 current language 使用
threading.local
) - 创建装饰器(例如租户感知
login_required
)、中间件或工厂以保护 View 并选择正确的模型 - 关于数据库,我使用了两种不同的场景:
- 设置多个数据库并配置 routing根据目前的租户。我首先使用它,但大约一年后切换到一个数据库。原因如下:
- 我们不需要高度安全的解决方案来分离数据
- 不同的租户使用的机型几乎都是一样的
- 我们必须管理大量数据库(并且没有构建简单的更新/迁移流程)
- 使用一个数据库和一些简单的映射表,例如用户和不同的模型。要添加额外的和租户特定的模型字段,我们使用 model inheritance .
- 设置多个数据库并配置 routing根据目前的租户。我首先使用它,但大约一年后切换到一个数据库。原因如下:
关于我们使用以下设置的环境:
从我的角度来看,此设置具有以下优点和缺点:
临:
- 一个知道当前租户的应用程序实例
- 项目的大部分内容不必为租户的特定问题而烦恼
- 在所有租户之间共享实体(例如消息)的简单解决方案
反对:
- 一个相当大的数据库
- 由于模型继承,一些非常相似的表
- 在数据库层不安全
当然,最好的架构在很大程度上取决于您的要求,如租户数量、模型的增量、安全要求等。
更新:在我们审查我们的架构时,我建议不要按照第 2-3 点中的指示重写 URL。我认为更好的解决方案是将 tenant_id
作为请求 header 并提取(第 4 点)tenant_id
在请求之外,类似 request.META.get('TENANT_ID', None)
.通过这种方式,您可以获得中性 URL,并且可以更轻松地使用 Django 内置函数(例如 {% url ...%}
或 reverse()
)或外部应用程序。
关于django - Django 上 Multi-Tenancy 应用程序的最佳架构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7194341/