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

2023-12-26

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

一些解释:

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

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

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

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

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

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

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

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

你怎么认为?


我们建立了多租户platform https://www.atizo.com/使用以下架构。我希望你能找到一些有用的提示。

  • 每个租户都有子域(t1.example.com)
  • 使用 url 重写,Django 应用程序的请求被重写为 example.com/t1 之类的内容
  • 所有 url 定义都带有类似的前缀(r'^(?P<tenant_id>[\w\-]+)
  • A 中间件 https://docs.djangoproject.com/en/1.3/topics/http/middleware/#writing-your-own-middleware处理并使用tenant_id并将其添加到请求中(例如request.tenant ='t1')
  • 现在,您可以在每个视图中使用当前租户,而无需在每个视图中指定tenant_id参数
  • 在某些情况下,您没有可用的请求。我通过将tenant_id绑定到当前线程解决了这个问题(类似于当前语言 https://github.com/django/django/blob/master/django/utils/translation/trans_real.py using threading.local )
  • 创建装饰器(例如租户意识login_required)、中间件或工厂来保护视图并选择正确的模型
  • Regarding to the databases I used two different scenarios:
    • Setup multiple databases and configure a routing https://docs.djangoproject.com/en/dev/topics/db/multi-db/#automatic-database-routing according to current tenant. I used this first but switched to one database after about one year. The reasons were the following:
      • 我们不需要高度安全的解决方案来分离数据
      • 不同的租户使用的几乎都是相同的型号
      • 我们必须管理大量数据库(并且没有构建简单的更新/迁移过程)
    • 使用一个数据库和一些简单的映射表,即用户和不同的模型。要添加其他和租户特定的模型字段,我们使用模型继承 https://docs.djangoproject.com/en/dev/topics/db/models/#model-inheritance.

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

  • Nginx http://wiki.nginx.org/
  • uWSGI http://projects.unbit.it/uwsgi/
  • PostgreSQL
  • 内存缓存 http://memcached.org/

从我的角度来看,这种设置有以下优点和缺点:

Pro:

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

Contra:

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

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

Update:当我们审查我们的架构时,我建议not按照第 2-3 点重写 URL。我认为更好的解决方案是把tenant_id作为请求标头并提取(第 4 点)tenant_id超出了类似的请求request.META.get('TENANT_ID', None)。通过这种方式,您可以获得中性 URL,并且更容易使用 Django 内置函数(例如{% url ...%} or reverse())或外部应用程序。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Django 上多租户应用程序的最佳架构 的相关文章

随机推荐

  • Objective-C enumerateObjectsUsingBlock 与快速枚举?

    以下两种方法的优点和缺点是什么 使用块枚举 https developer apple com documentation foundation nsarray 1415846 enumerateobjectsusingblock lang
  • android错误:删除片段时“提交已调用”

    我想实现一个有片段的活动 当我点击 Fragment1 时 Fragment2 被调用 当我点击 Fragment2 时 Fragment2 应该从屏幕上删除 我通过在 onCreateView 中调用 Fragment2 LinearLa
  • Visual Studio Team Services - 构建失败,定义错误?

    我从事一个项目已经有一段时间了 现在我想使用 Visual Studio Team Services 在本地 Visual Studio 中的构建不会给出错误 并且应用程序按预期工作 我已将此工作代码签入 VSTS 因此它位于存储库中并且可
  • 计数返回空白而不是 0

    今天是个好日子 这是我的代码 SELECT Expired Item DateName mm DATEADD MM 4 AE fld LOAN as Month COUNT PIT fld ID COUNT SUM PIT fld GRAM
  • Android 上的 kivy/Python 缺少 Unicode 编解码器?

    我有一个在 kivy 下运行的程序 它在 Windows 上运行良好 但在 Android 上打开文件失败 两个平台上都是 1 8 0 奇怪的是 当我明确要求 utf 8 时 错误消息表明它正在尝试解码 ASCII 而且该文件中的任何位置都
  • 如何解压和打包pkg文件?

    我有一个由 Install Maker for Mac 创建的 pkg 文件 我想替换 pkg 中的一个文件 但我必须在Linux系统下执行此操作 因为这是下载过程的一部分 当用户开始下载文件时 服务器必须替换 pkg 中的一个文件 我有一
  • 编译 gtkmm 时出现问题

    操作系统 Fedora 14 编译器 g GCC 4 5 1 20100924 红帽 4 5 1 4 我通过 yum 从存储库安装了 gtkmm24 devel 为了确保安装按计划进行 我决定尝试页面上的示例之一 include
  • Oracle 中的动态表分区

    我正在为我的应用程序构建一个数据库存储 该存储由一个具有巨大数据量 数亿条记录 的表组成 我计划在日期字段上建立索引 因为我将不时地对给定时间段内的所有记录进行批量恢复 例如 检索第二天的所有记录 午夜 由于记录数量巨大并且性能是该系统中的
  • 递归地 (?) 将 LINQ 谓词组合成单个谓词

    编辑 我问错了问题 real我遇到的问题已经结束将 LINQ to SQL 谓词组合成单个谓词 https stackoverflow com questions 3782940 compose linq to sql predicates
  • 在 OS X 上以 32 位模式使用 virtualenv 运行非系统 Python

    简短的问题使用 virtualenv virtualenvwrapper 是否可以添加前缀python调用链接到特定的虚拟环境 背景我想使用多个虚拟环境已安装酿造 https github com mxcl homebrewPython 2
  • 如何从 Kotlin DSL build.gradle 中的所有依赖项中排除库?

    我开始迁移build gradle 时髦 到build gradle kts Kotlin DSL 事情是这样的com google common util concurrent ListenableFuture from com goog
  • Netbeans:自动格式 - 防止变量赋值时出现空格格式

    我更喜欢这样的格式化作业 foo bar long foo bar 而不是这个 foo bar long foo bar 然而 Netbeans 在使用自动格式时使用后者 有人知道如何解决这个问题吗 这个问题已经发布三年了 但我认为它非常有
  • 电子邮件主题分隔符间距中的重音单词 - 如何阻止这种情况?

    我们有一个自定义的 php 电子邮件营销应用程序 还有一个有趣的问题 如果邮件的主题行包含带有重音符号的单词 则会 吞掉 该单词与下一个单词之间的空格 示例 短语 安赫尔 里奥斯 埃斯库查 索普伦德 显示 至少通过 gmail 和 Lotu
  • 数组和右值(作为参数)

    我想知道是否有任何方法可以区分以下代码中显示的函数调用 以数组作为参数 include
  • Python:遍历列表

    我有一个智力挑战谜题 我想用 python 来解决 他们给出了 4 个数字 25 28 38 35 他们希望我们将这些数字放在 一种可能的解决方案是 25 38 35 28 我尝试过 从数字中列出一个列表 用一些循环和 if 来迭代它们 l
  • 无法从我的学校网站获取我的日程安排数据。使用 cURL 登录不起作用

    Edit 为什么要负一呢 我想做的是 我正在尝试使用 cURL 登录我的学校网站并获取时间表以将其用于我的 AI 因此 我需要使用我的通行证和号码登录 但学校网站上的表格还需要一个隐藏的 令牌
  • 将多个 .sql 表转储文件合并到单个文件中

    假设我有数据库A和表b 给定多个 sql 文件 b1 b2 bn 其中每个文件对应于 b 的互斥表转储 我如何将所有文件 b1 b2 bn 合并到单个 sql 表文件中 或者我如何将各个文件的导入合并到一个表中 没有特殊的工具可以做到这一点
  • 循环遍历所有文件夹及其所有子文件夹VBA

    我知道这个问题之前被问过很多次 我已经检查了之前的建议 但我无法让我的代码运行 所以 我有一个名为 Report 的文件夹 其中也包含多个文件夹 这些文件夹包含 xlsx 和 zip 文件 每个文件还包含一个名为 2016 的文件夹 其下有
  • /www 之外的指定虚拟主机上的 Wampserver 403

    当我尝试在 c wamp www 目录之外创建虚拟主机时 Wampserver 告诉我访问被拒绝 我可以在该目录中制作一个罚款 即使对文件夹建立符号链接也可以 但我宁愿不必使用符号链接 为什么不起作用 这是我在 httpd conf 末尾使
  • Django 上多租户应用程序的最佳架构

    我一直在思考创建基于多租户应用程序的正确 最佳方法 关于姜戈 一些解释 应用程序可由多个租户 tenant1 tenant2 使用 所有租户个人数据都必须受到保护 防止其他租户 及其用户 访问 租户可以选择为应用程序对象创建额外的自定义字段