RoR SaaS应用程序的体系结构

时间:2011-03-03 03:08:17

标签: ruby-on-rails ruby-on-rails-3 architecture saas

我已经完成了大量的基础RoR工作,但是并没有真正面对扩展和运行多个应用程序。

我正在为客户构建应用程序,我希望将其推向类似行业的其他用户,但我正在努力应对高级架构。似乎没有必要为每个客户端运行完全独立的应用程序实例,但我不知道如何为各种用户加载不同的配置/布局/功能。我不希望每个单独的应用程序都具有极高的流量,因此每个应用程序拥有唯一的实例/数据库似乎是浪费。然而,每个实例可能都需要自己的CSS以及可能的功能的不同配置。

这是否可以使用子域轻松完成?我可以根据此加载不同的配置吗?有没有人了解37信号应用程序如何根据帐户管理不同的配置?

2 个答案:

答案 0 :(得分:6)

当我们为我们的申请做出同样的决定时,我们考虑了几件事......

首先,我们考虑了复杂性。当您开始将多个客户添加到同一数据库中时,您需要考虑如何对其数据进行分段。如果你为一个客户编写了应用程序,你可能不必太担心这个问题。在许多情况下,这些问题根植于核心数据模型,这将导致重构的批次(如果不是完全重写)。

此外,你永远不会逃避这种复杂性。特别是在面向业务的应用程序中,将一个客户的数据暴露给另一个客户可能是致命的。你总是需要添加额外的代码和许多额外的测试来保护自己。

其次,我们考虑了成本。当我们考虑在相同的RDS实例中我们可以在同一个Amazon EC2实例上使用自己的Amazon RDS数据库在自己的Rails实例中运行多个客户时,成本变得非常有吸引力。由于我们有一个面向企业的应用程序,并且不会很快就会有超过200个客户,我们可能会在3到3年的时间内讨论几千美元的额外托管成本。

当我们比较成本与复杂性时,我们得出结论,让每个人都处于自己的实例中是非常值得的理论扩展问题。

此方法的缺点是您必须确保能够跟上维护,监视和升级多个实例的步伐。像Chef这样的一些简单的脚本和工具可以在这里走很长的路。

答案 1 :(得分:3)

<强>声明

确保您实际上能够推销您正在写给其他客户的应用程序。您是否与客户签订了合同?如果是这样,他们很可能拥有您正在编写的代码的权利,在这种情况下,您将违反合同。


关于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

如果你想能够拥有功能,你可以打开和关闭最简单的方法可能是添加一个位掩码(有一个gem for bit masks),它可以让你查询可用的配置。这不会扩展到一定数量的功能,但将是一个良好的开端。您最终会得到以下视图代码:

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

确保无论你做出什么样的选择,你都可以做最简单的事情。