Написание мультитенантного приложения Rails 3 для развертывания на Heroku - PullRequest
13 голосов
/ 07 мая 2011

Я создаю приложение Rails 3 для развертывания на Heroku, и мне интересно, есть ли какие-либо рекомендации по работе с многопользовательским режимом в моих моделях. Полгода назад был опубликован соответствующий вопрос ( # 3776593 ), но он не получил много ответов. Я также смотрел презентацию Гая Наора о написании мультитенантных приложений с Rails , но кажется, что 2 из 3 предложенных решений не будут работать на Heroku. Я бы сослался на них, но новые пользователи Stackoverflow ограничены двумя гиперссылками.

Я также встречал следующие инструменты:

Просто интересно, есть ли у вас опыт работы с драгоценным камнем с несколькими арендаторами или с драгоценным камнем с простыми рельсами? Похоже, что самым простым решением было бы просто добавить принадлежать ко всем моим моделям, которые должны быть под учетной записью, но мне бы очень хотелось узнать, что вы используете в реальном мире!

Ответы [ 3 ]

6 голосов
/ 23 мая 2011

Как автор мультитенантного самоцвета, я явно предвзят, но я действительно считаю, что это отличное решение! Цель самоцвета состоит в том, чтобы упростить эту общую потребность приложения и сделать ее тривиальной для реализации.

Альтернативой "старой школы" является использование цепочки объектов rails, чтобы гарантировать, что все запросы выполняются через связанный родительский элемент. Проблема с этим подходом состоит в том, что ваш объект Арендатора становится свалкой для ассоциаций has_many.

class Tenant
  has_many :users
end
# query for users in the current tenant
current_tenant.users.find params[:id]

Многопользовательский гем решает эту проблему, гарантируя, что все сгенерированные запросы автоматически узнают о текущем арендаторе. И это также гарантирует, что новые записи создаются и автоматически назначаются текущему арендатору, поэтому вам не нужно добавлять никаких специальных обратных вызовов before_save.

например:

Multitenant.with_tenant current_tenant do
  # queries within this block are automatically
  # scoped to the current tenant
  User.all

  # records created within this block are
  # automatically assigned to the current tenant
  User.create :name => 'Bob'
end
6 голосов
/ 07 мая 2011

Подходы варьируются от «не делить ничего», что обычно означает одну базу данных на каждого арендатора, до «совместного использования всего», что обычно означает, что каждая таблица содержит строки из множества арендаторов. Спектр (ниже) может быть разбит по степени изоляции, по стоимости (то есть стоимости на одного арендатора) и по простоте аварийного восстановления.

  • Одна база данных на каждого арендатора; высокая стоимость, высочайшая изоляция, простое восстановление.
  • Одна схема на каждого арендатора; стоимость между двумя другими, хорошая изоляция, довольно простое восстановление, но восстановление обычно снижает производительность для других арендаторов.
  • Разделить таблицы между арендаторами; низкая стоимость, низкая изоляция (общие таблицы), сложное аварийное восстановление (восстановление обычно означает восстановление нескольких строк для каждой таблицы). Восстановление обычно ухудшает производительность "много" для других арендаторов.

Все это в определенной степени зависит от платформы. «Одна база данных на клиента» имеет наивысшую изоляцию, когда dbms запрещает запросам доступ к более чем одной базе данных. Но некоторые платформы позволяют выполнять запросы к нескольким базам данных.

В MSDN есть достойная статья, которая поразила всех: Мультитенантная архитектура данных .

Но если вы ограничены Heroku, вам придется выбрать опцию, которую поддерживает Heroku. Я не знаю, какими могут быть эти варианты, но я знаю, что вам лучше не использовать SQLite в разработке. Развертывания Heroku будут работать на PostgreSQL; вам нужно разрабатывать против PostgreSQL.

2 голосов
/ 11 февраля 2013

Я собираюсь начать это предприятие (реализуя мультитенантность для небольшого рельсового приложения), и во время исследования я наткнулся на этот пост SO.

Удивительно, что никто не упомянул о великолепной заставке RyanB по внедрению MT с использованием схем PostgreSQL, поддерживаемых Heroku.

Вот ссылка на скринкаст http://railscasts.com/episodes/389-multitenancy-with-postgresql.

Концепция:

В приложении rails мы можем установить путь поиска для pg-соединения

      connection.schema_search_path = "schema1, schema2, ..."

любые последующие действия будут выполнены над схемой1, если она найдет там соответствующую таблицу. В противном случае он ищет таблицу в schema2 и так далее. Пребывание со всей схемой приложения, включая арендатора, будет общедоступным, и обычная практика - сделать все таблицы, кроме арендатора, пустыми в общедоступной схеме.

Регистрация нового арендатора:

Добавьте функцию after_create в модель Tenant, чтобы создать новую схему для нового арендатора и создать все (загрузить schema.rb) таблицы приложений (кроме Tenant) в эту новую схему.

Пользователь:

когда пользователь посещает subdomain1.myapp.com, находит схему для этого субдомена из таблицы арендаторов и задает путь поиска соединения 'schema1, public' и аутентифицирует пользователя.

Обратите внимание, мое намерение состоит в том, чтобы просто охватить концепцию, лежащую в основе решения. Обратитесь к скринкасту RyanB для актуального решения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...