我一直在思考创建基于多租户应用程序的正确/最佳方法
关于姜戈。
一些解释:
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(使用前将#替换为@)