Django 上多租户应用程序的最佳架构

发布于 2024-12-01 13:35:15 字数 413 浏览 1 评论 0原文

我一直在思考创建基于多租户应用程序的正确/最佳方法 关于姜戈。

一些解释:

  • 应用程序可以由多个租户(tenant1、tenant2、...)使用。

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

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

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

1)通过子域等方式分隔每个租户,并在底层使用特定于租户的数据库

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

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

最好的设置是什么?优点和缺点在哪里?

你怎么认为?

I've been brooding over the right/optimal way to create a multitenancy application based
on Django.

Some explanation:

  • Application can be used by several tenants (tenant1, tenant2, ...,).

  • All tenant-individual data has to be secured against access of other tenants (and their users).

  • Optionally tenants can create additional custom-fields for application-objects.

  • Of course, underlying hardware limits number of tenants on one "system".

1) Separating each tenant by e.g. sub-domain and using tenant-specific databases in the underlying layer

2) Using some tenant-ID in the model to separate the tenant-data in the database

I am thinking about deployment-processes, performance of the system-parts (web-server(s), database-server(s), working-node(s),...)

What would be the best setup ? Where are the pro's and con's?

What do you think?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

浮华 2024-12-08 13:35:15

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

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

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

从我的角度来看,这个设置有关注专业人士和缺点:

优点:

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

缺点:

  • 一个相当大的数据库
  • 一些非常相似的表,因为模型继承
  • 在数据库层上不受保护

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

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

We built a multitenancy platform using the following architecture. I hope you can find some useful hints.

  • Each tenant gets sub-domain (t1.example.com)
  • Using url rewriting the requests for the Django application are rewritten to something like example.com/t1
  • All url definitions are prefixed with something like (r'^(?P<tenant_id>[\w\-]+)
  • A middleware processes and consumes the tenant_id and adds it to the request (e.g. request.tenant = 't1')
  • Now you have the current tenant available in each view without specifying the tenant_id argument every view
  • In some cases you don't have the request available. I solved this issue by binding the tenant_id to the current thread (similar to the current language using threading.local )
  • Create decorators (e.g a tenant aware login_required), middlewares or factories to protect views and select the right models
  • Regarding to the databases I used two different scenarios:
    • Setup multiple databases and configure a routing according to current tenant. I used this first but switched to one database after about one year. The reasons were the following:
      • We didn't need a high secure solution to separate the data
      • The different tenants used almost all the same models
      • We had to manage a lot of databases (and didn't built an easy update/migration process)
    • Use one database with some simple mapping tables for i.e. users and different models. To add additional and tenant specific model fields we use model inheritance.

Regarding the environment we use the following setup:

From my point of view this setup has the following pro's and con's:

Pro:

  • One application instance knowing the current tenant
  • Most parts of the project don't have to bother with tenant specific issues
  • Easy solution for sharing entities between all tenants (e.g. messages)

Contra:

  • One quite large database
  • Some very similar tables due to the model inheritance
  • Not secured on the database layer

Of course the best architecture strongly depends on your requirements as number of tenants, the delta of your models, security requirements and so on.

Update: As we reviewed our architecture, I suggest to not rewrite the URL as indicated in point 2-3. I think a better solutions is to put the tenant_id as a Request Header and extract (point 4) the tenant_id out of the request with something like request.META.get('TENANT_ID', None). This way you get neutral URLs and it's much easier to use Django built-in functions (e.g. {% url ...%} or reverse()) or external apps.

披肩女神 2024-12-08 13:35:15

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

Here are some pointers to related discussions:

深海蓝天 2024-12-08 13:35:15

I recommend taking a look at https://github.com/bcarneiro/django-tenant-schemas. It will solve your problems a bit like Reto mentioned, except that it uses postgresql schemas.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文