【问题标题】:Architecture for RoR SaaS applicationRoR SaaS 应用程序的架构
【发布时间】:2011-07-07 18:25:35
【问题描述】:
我已经完成了相当多的基础 RoR 工作,但在扩展和运行多个应用程序方面并没有真正面临太多问题。
我正在为一个客户构建一个应用程序,希望向类似行业的其他用户推销,但我正在为高级架构而苦苦挣扎。似乎没有必要为每个客户端运行一个完全独立的应用程序实例,但我不知道如何为不同的用户加载不同的配置/布局/功能。我不希望每个单独的应用程序具有极高的流量,因此每个应用程序拥有唯一的实例/数据库似乎是一种浪费。然而,每个实例都可能需要自己的 CSS 以及可用功能的不同配置。
这是可以使用子域轻松完成的事情吗?我可以基于此加载不同的配置吗?有没有人了解 37 个信号应用程序如何根据帐户管理不同的配置?
【问题讨论】:
标签:
ruby-on-rails
ruby-on-rails-3
architecture
saas
【解决方案1】:
当我们为我们的应用程序做出相同的决定时,我们考虑了几件事......
首先,我们考虑了复杂性。当您开始将多个客户添加到同一个数据库中时,您需要考虑如何分割他们的数据。如果您为一位客户编写了应用程序,您可能不必担心太多。在许多情况下,这些问题根源于核心数据模型,这将导致大量重构(如果不是完全重写的话)。
此外,您永远无法摆脱这种复杂性。尤其是在面向业务的应用程序中,将一个客户的数据暴露给另一个客户可能是致命的。您总是需要添加额外的代码和大量额外的测试来保护自己免受这种情况的影响。
其次,我们考虑了成本。当我们考虑到我们可以在同一个 Amazon EC2 实例上运行多个客户自己的 Rails 实例时,在同一个 RDS 实例中使用他们自己的 Amazon RDS 数据库,成本变得非常有吸引力。由于我们有一个面向业务的应用程序,并且短期内不会有超过 200 个客户,因此我们可能会在 3 到 5 年内增加几千美元的额外托管成本。
当我们比较成本与复杂性时,我们得出结论,让每个人都在自己的实例中是非常值得的理论上扩展问题。
这种方法的缺点是您必须确保能够跟上维护、监控和升级多个实例的步伐。一些简单的脚本和工具(例如 Chef)可以在这里大有帮助。
【解决方案2】:
免责声明
确保您确实能够向其他客户推销您正在编写的应用程序。你和你的客户签合同了吗?如果是这样,他们很可能拥有您正在编写的代码的权利,在这种情况下,您将违反您的合同。
维基百科上有一篇关于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 %>
确保无论你做出什么选择,你都会做最简单的事情。