оптимальная архитектура для мультитенантного приложения на django


Я размышлял над правильным / оптимальным способом создания мультитенантного приложения на основе на Джанго.

объяснение:

  • приложение может быть использовано несколькими арендаторами (tenant1, tenant2, ...,).

  • все клиента-персональные данные должны быть защищены от доступа других арендаторов (и их пользователей).

  • дополнительно арендаторы могут создавать дополнительные настраиваемые поля для объект приложения.

  • конечно, базовое оборудование ограничивает количество арендаторов на одной "системе".

1) разделение каждого клиента, например, поддоменом и использование специфичных для клиента баз данных в базовом слое

2) использование некоторого идентификатора клиента в модели для разделения данных клиента в базе данных

Я думаю о развертывании-процессы, производительность системы-части (веб-сервер(ы), база данных-сервер(ы), рабочий узел(ы),...)

какая была бы лучшая настройка ? Где плюсы и минусы?

Что вы думаете?

3 56

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()) или внешних приложений.

вот некоторые указатели на связанные обсуждения:

Я рекомендую взглянуть на https://github.com/bcarneiro/django-tenant-schemas. это решит ваши проблемы немного, как упоминалось Reto, за исключением того, что он использует схемы postgresql.