оптимальная архитектура для мультитенантного приложения на django
Я размышлял над правильным / оптимальным способом создания мультитенантного приложения на основе на Джанго.
объяснение:
приложение может быть использовано несколькими арендаторами (tenant1, tenant2, ...,).
все клиента-персональные данные должны быть защищены от доступа других арендаторов (и их пользователей).
дополнительно арендаторы могут создавать дополнительные настраиваемые поля для объект приложения.
конечно, базовое оборудование ограничивает количество арендаторов на одной "системе".
1) разделение каждого клиента, например, поддоменом и использование специфичных для клиента баз данных в базовом слое
2) использование некоторого идентификатора клиента в модели для разделения данных клиента в базе данных
Я думаю о развертывании-процессы, производительность системы-части (веб-сервер(ы), база данных-сервер(ы), рабочий узел(ы),...)
какая была бы лучшая настройка ? Где плюсы и минусы?
Что вы думаете?
3 ответа:
мы построили мультитенантности платформа используя следующую архитектуру. Я надеюсь, что вы можете найти некоторые полезные советы.
- каждый клиент получает поддомен (t1.example.com)
- С помощью перезаписи url запросы для приложения Django переписываются на что-то вроде example.com/t1
- все определения url имеют префикс что-то вроде
(r'^(?P<tenant_id>[\w\-]+)
- A middleware процессы и потребляет tenant_id и добавляет его к запросу (например, запрос.tenant = 't1')
- теперь у вас есть текущий арендатор, доступный в каждом представлении без указания аргумента tenant_id every view
- в некоторых случаях у вас нет запросов. Я решил эту проблему путем привязки tenant_id к текущему потоку (аналогично текущий язык используя
threading.local
)- создание декораторов (например, арендатор знает
login_required
), middlewares или фабрики для защиты взглядов и Выберите правильные модели- что касается баз данных, я использовал два разных сценария:
- настройка нескольких баз данных и настроить маршрут в соответствии с текущим арендатором. Я использовал это сначала, но переключился на одну базу данных примерно через год. Причины были следующие:
- нам не нужно было высокое безопасное решение для разделения данных
- разные арендаторы использовали почти все те же модели
- мы для управления большим количеством баз данных (и не построил простой процесс обновления/миграции)
- используйте одну базу данных с некоторыми простыми таблицами отображения для т. е. пользователей и различных моделей. Для добавления дополнительных и специфичных для клиента полей модели мы используем модель наследования.
в отношении окружающей среды мы используем следующие настройки:
С моей точки зрения эта установка имеет следующие плюсы и минусы:
Pro:
- один экземпляр приложения, знающий текущего арендатора
- большинство частей проекта не должны беспокоиться о конкретных проблемах арендатора
- простое решение для совместного использования объектов между всеми жильцами (например, сообщения)
Contra:
- одна довольно большая база данных
- некоторые очень похожие таблицы из-за модель наследования
- не защищен на уровне базы данных
конечно, Лучшая архитектура сильно зависит от ваших требований, таких как количество арендаторов, Дельта ваших моделей, требования безопасности и так далее.
обновление: поскольку мы рассмотрели нашу архитектуру, я предлагаю не перепишите URL, как указано в пункте 2-3. Я думаю, что лучшее решение-поставить
tenant_id
В качестве заголовка запроса и извлечения (пункт 4)tenant_id
из запроса с чем-то вродеrequest.META.get('TENANT_ID', None)
. Таким образом, вы получаете нейтральные URL-адреса, и гораздо проще использовать встроенные функции Django (например,{% url ...%}
илиreverse()
) или внешних приложений.
вот некоторые указатели на связанные обсуждения:
- билет Джанго #15089: "ВНО.сайты и мультитенантность"
- обсуждение в группах Google, см. esp. Решение Яри Пеннанена в конце
- the патч введение threadlocals-based multi-tenancy в Мезонине; см. esp.
mezzanine.utils.sites.current_site_id
,mezzanine.core.models.SiteRelated
иmezzanine.core.request
- the django-simple-multitenant повторно используемые приложения на PyPI
Я рекомендую взглянуть на https://github.com/bcarneiro/django-tenant-schemas. это решит ваши проблемы немного, как упоминалось Reto, за исключением того, что он использует схемы postgresql.