构建“大型”Rails应用程序的最佳实践

时间:2009-11-29 20:49:31

标签: ruby-on-rails apache

我的问题是寻求最佳实践,一般建议和见解,而不是解决特定问题。

我正处于规划Rails项目的早期阶段,我认为这个项目相当大。在最简单的层面上,它为目标用户提供了一个千篇一律的CMS。因此,用户注册并选择一个子域名,并获得一个非常基本的CMS网站。

因此,整个应用程序有大约4个不同的“边”:

  • 向最终用户销售产品的销售网站 - www.myapp.com
  • 中央管理区域,员工可以登录和管理帐户等 - www.myapp.com/superadmin
  • 用户自己的网站 - subdomain.myapp.com
  • 用户的管理区域/ CMS - subdomain.myapp.com/admin

所以我真正想要的是构建应用程序的最佳实践。即是应该将它们全部归入一个巨大的应用程序,还是应该分成两个(或更多)较小的应用程序?

如果部署为一个应用程序,我可以看到有关路由的问题,因为销售网站和用户的网站都需要设置根路径,而且我不希望通过用户访问我为销售网站设置的路由'网站。任何事情都可以在Rails或Apache级别(mod重写?)中完成,以确保不会混淆路由?

如果拆分超过2个或更多应用程序,如何让应用程序共享同一个数据库?这是一个好主意吗?拆分应用程序有什么好处(比如在应用程序的一个区域中隔离问题,而不是将所有内容都关闭)?

我意识到这篇文章提出了不少不同的问题,但感谢您给我的任何建议和见解。

6 个答案:

答案 0 :(得分:6)

我认为将您的问题分离到单独的应用程序中的好处超过了成本。我可能会开始只有2个应用程序(一个用于主站点和superadmin,一个用于客户端站点和管理员),访问同一个数据库,但你可以做4个。

缺点是你没有真正的隔离,因为你的所有应用程序都绑定到一个数据库。您最终会遇到数据库的扩展问题,但是从一个数据库开始简单就可以启动了。稍后扩展的一种策略是添加客户端站点和主站点应用程序使用的从属数据库,而管理应用程序使用主数据库。这个以及一系列缓存将让你走得很远。

让多个rails应用程序访问一个数据库没有任何问题,但是您需要一种方法来跨应用程序共享公共代码。你的模特大部分。之前我已经完成了这个操作,将我的所有模型都放在一个插件中,我作为git中的子模块或svn中的外部模块共享。拥有单独的应用程序将使每个应用程序更小,更易于维护。

但是,您在哪里保留迁移?你在哪里测试你的模型?我会选择superadmin应用程序。此外,您对模型或架构进行了更改,现在您必须检查2-4个应用程序并确保它们仍然有效!

更好的隔离,通过Web API(SOA)分离数据库和应用程序间通信,您不必担心这一点。我认为SOA是追求某一点的方法,但是当你刚开始时,SOA可能为时过早。

无论如何,拥有单独的应用程序可以为SOA做好准备,但您不必超越单个数据库就可以启动。

答案 1 :(得分:5)

我会把这一切都捆绑到同一个应用程序中,因为你不会在所有应用程序中复制类(模型,插件等)。另外:运行4个应用程序意味着你将有4个进程全部消耗内存,因为它们已经加载了4个独立的Rails堆栈。

将其编译为一个应用程序可以消除此问题。对于销售网站和用户网站之间的问题,必须有as mentioned earliersubdomain_fu,可以解决不同的根。让我展开一些来自我的应用程序的示例代码:

map.with_options :conditions => {:subdomain => 'logs'} do |admin|
  admin.resources :channels do |channel|
    channel.resources :logs
  end
  map.root :channels
  map.connect ':id', :controller => "channels", :action => "show"
end

正如我们在此处看到的,:conditions方法的with_options:subdomain设置为logs,这意味着任何进入 logs.mysite.com的内容会填补这些条件,因此会以这种方式发送。

现在,在这个路由文件中,我将所有其他内容包含在一个类似的块中:

map.with_options :conditions => {:subdomain => nil} do |admin|
  # shebang!
end

前往 mysite.com 的所有内容都将转到这些路线。

最后,将它全部编译成一个超级超级应用程序将消除数据库共享问题。

答案 2 :(得分:3)

我看到分离到多个应用程序的最大问题是您失去了灵活性。如果将来以前的管理任务(例如,上传某种类型的文件)成为“用户任务”,会发生什么?您必须将代码从一个应用程序移动到另一个应用程序。

我会将所有内容保留在单个应用程序中 - 并使用角色来过滤每个用户可以看到和执行的操作。在开始时可能会有点困难,但它会在不久的将来付出代价。

查看授权框架,例如declarative_authorizationcancan

答案 3 :(得分:2)

好吧,因为没有其他人发言,我鼓励你阅读面向服务的架构。 Dan Chak的“企业Rails”这本书有一些很好的材料,你可以通过Google Books阅读很多内容。尝试第13章,here.我认为它会让你走上正轨。

答案 4 :(得分:0)

我发现您遇到的问题是,尝试构建一个具有各种子域的应用程序,因此一个插件的account_manager可以解决您的问题。

如果你的应用程序足够大,可以维护而不是将它们拆分成两三个也不错,使用restfull资源可以让你的应用程序相互通信,等等。

如果您考虑将它们放在一个数据库下,那么在使用establish_connection的rails中非常简单。

我认为您可以将应用程序拆分为三到四个不同的应用程序,其中集群将处理每个应用程序请求,因此速度会很好。您也可以在一个应用程序中捆绑类似的功能,以确保维护它们很容易。

http://www.railslodge.com/plugins/1113-subdomain-fu

答案 5 :(得分:0)

就我的研究而言,大多数公司都会选择使用多个数据库的SOA。以下是有关Linked InEBay如何思考此问题的一些信息的链接。为了回应PreciousBodilyFluids,我强烈推荐Dan Chak的Enterprise Rails一书。