Архитектура для приложения RoR SaaS

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

Я собираюсь создать приложение для клиента, которое, как я надеюсь, будет продаваться другим пользователям в подобных отраслях, но я борюсь с архитектурой высокого уровня. Кажется ненужным запускать отдельный экземпляр приложения для каждого клиента, но я не знаю, как загружать различные конфигурации/макеты/функции для разных пользователей. Я не ожидаю, что каждое отдельное приложение будет иметь чрезвычайно высокий трафик, поэтому кажется, что у каждого из них есть уникальный экземпляр/база данных. Тем не менее, для каждого экземпляра, вероятно, потребуется собственный CSS, а также потенциально другая конфигурация доступных функций.

Это что-то, что можно легко сделать с помощью поддоменов? Могу ли я загрузить различные конфигурации на основе этого? Кто-нибудь знает, как приложения 37 сигналов управляют различными конфигурациями на основе учетной записи?

Ответ 1

Когда мы принимали такое же решение для нашего приложения, мы рассмотрели несколько вещей...

Прежде всего, мы рассмотрели сложность. Когда вы начинаете добавлять несколько клиентов в одну и ту же базу данных, вам нужно подумать о том, как вы собираетесь сегментировать свои данные. Если вы написали приложение для одного клиента, вам, вероятно, не пришлось слишком беспокоиться об этом. Во многих случаях эти проблемы основаны на базовой модели данных, что приведет к большому количеству рефакторинга (если не полной перезаписи).

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

Во-вторых, мы рассмотрели стоимость. Когда мы подумали, что мы можем запускать несколько клиентов в своих собственных экземплярах Rails на одном экземпляре Amazon EC2 со своими собственными базами данных Amazon RDS в одном экземпляре RDS, стоимость стала очень привлекательной. Поскольку у нас есть приложение, ориентированное на бизнес, и в ближайшее время у нас не будет более 200 клиентов, мы, вероятно, будем говорить о нескольких тысячах долларов за дополнительные расходы на хостинг в течение 3-5 лет.

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

Недостатком этого подхода является то, что вы должны следить за тем, чтобы вы не отставали от поддержки, мониторинга и обновления нескольких экземпляров. Некоторые простые скрипты и инструменты, такие как шеф-повар, могут пройти долгий путь здесь.

Ответ 2

Отказ

Убедитесь, что вы действительно можете продавать приложение, которое вы пишете другим клиентам. Вы подписали контракт с вашим клиентом? Если это так, вероятно, они владеют правами на код, который вы пишете, и в этом случае вы будете нарушать ваш контракт.


Там действительно хорошая статья о wikipedia о Multitenancy, которую вы обязательно должны прочитать. Он ответит на многие ваши вопросы и заставит вас задуматься о своей стратегии. Мое предложение состоит в том, чтобы создать ваше приложение таким образом, чтобы вы могли поддерживать многопользовательскую работу, так как это было гораздо труднее сделать после этого факта.

Приложения 37s не позволяют изменять настройки, отличные от цветовой схемы, которые, вероятно, выполняются с помощью параметра, который изменяет таблицу стилей. Например:

<%= stylesheet_link_tag(@tenant.style.name) %>

Вы загрузите арендатора на основе субдомена:

before_filter :load_tenant, :if => :tenant_request?
def tenant_request?
  request.subdomain.present? && !request.subdomain == 'www'
end    

def load_tenant
  @tenant = Tenant.find_by_name(request.subdomain)
end

Если вы хотите иметь функциональность, вы можете включить и выключить самый простой способ, вероятно, добавить битовая маска (там драгоценный камень для бит-масок), которые позволяют запросить доступную дополнительную информацию. Это не повлияло бы на определенное количество функций, но было бы хорошим началом. Вы получите код вида, например:

<% if tenant.has_feature?(:messaging) %>
  <li><%= link_to 'Messages', messages_url %></li>
<% end %>

Удостоверьтесь, что любой выбор, который вы делаете, выполняет самую простую вещь, которая работает.