оптимальная архитектура для мультитенантного приложения на django - PullRequest
60 голосов
/ 25 августа 2011

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

Некоторое объяснение:

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

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

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

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

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

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

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

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

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

Ответы [ 3 ]

55 голосов
/ 25 августа 2011

Мы создали многопользовательскую платформу , используя следующую архитектуру.Я надеюсь, что вы найдете несколько полезных советов.

  • Каждый арендатор получает поддомен (t1.example.com)
  • При переопределении URL запросы на приложение Django переписываются во что-токак example.com/t1
  • Все определения URL имеют префикс с чем-то вроде (r'^(?P<tenant_id>[\w\-]+)
  • A middleware обрабатывает и использует tenant_id и добавляет его к запросу (например,request.tenant = 't1')
  • Теперь у вас есть текущий арендатор, доступный в каждом представлении, без указания аргумента tenant_id для каждого представления
  • В некоторых случаях запрос не доступен.Я решил эту проблему, привязав tenant_id к текущему потоку (аналогично текущему языку с использованием threading.local)
  • Создание декораторов (например, осведомленных об арендаторе login_required), промежуточного программного обеспечения или фабрикдля защиты представлений и выбора правильных моделей
  • Что касается баз данных, я использовал два разных сценария:
    • Настройка нескольких баз данных и настройка маршрутизации в соответствии с текущим арендатором.Я использовал это сначала, но переключился на одну базу данных примерно через год.Причины были следующие:
      • Нам не требовалось высоконадежное решение для разделения данных
      • Разные арендаторы использовали практически все одинаковые модели
      • Нам пришлось управлятьмного баз данных (и не было простого процесса обновления / миграции)
    • Использовать одну базу данных с несколькими простыми таблицами сопоставления для пользователей и разных моделей.Чтобы добавить дополнительные и специфичные для арендатора поля модели, мы используем наследование модели .

В отношении среды мы используем следующую настройку:

С моей точки зрения, эта установка имеет следующие плюсы и минусы:

Pro:

  • Один экземпляр приложения знает текущего арендатора
  • Большинство частей проектане нужно беспокоиться о специфических проблемах арендаторов
  • Простое решение для совместного использования сущностей всеми арендаторами (например, сообщениями)

Против:

  • Один довольнобольшая база данных
  • Некоторые очень похожие таблицы из-за наследования модели
  • Не защищены на уровне базы данных

Конечно, лучшая архитектура сильно зависит от ваших требований, как числоарендаторов, дельта ваших моделей, требования безопасности и пр.

Обновление : Поскольку мы рассмотрели нашу архитектуру, я предлагаю , а не переписать URL, как указано в пункте 2-3.Я думаю, что лучшее решение - поместить tenant_id в качестве заголовка запроса и извлечь (пункт 4) tenant_id из запроса с помощью чего-то вроде request.META.get('TENANT_ID', None).Таким образом, вы получаете нейтральные URL-адреса, и гораздо проще использовать встроенные функции Django (например, {% url ...%} или reverse()) или внешние приложения.

4 голосов
/ 31 января 2013

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

1 голос
/ 05 февраля 2013

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

...