5

我正在开发一个非常典型的 Web 应用程序。用户体验的主要组成部分是网站所有者将在其首页上安装的小部件。每次他们的首页加载时,小部件都会与我们的服务器对话并显示一些返回的数据。

所以这个 Web 应用程序有两个组件:

  1. 网站所有者用来配置其小部件的前端 UI
  2. 响应小部件的 web api 调用的后端组件

以前我们在 PHP 中运行所有这些。现在我们正在试验 Rails,这对于#1(前端 UI)来说非常棒。问题是如何有效地执行 #2,即小部件信息的后端服务。显然,这比前端的负载要高得多,因为每次首页加载到我们客户的网站之一时都会调用它。

我可以看到两种明显的方法:

A. Parallel Stack : 建立一个并行堆栈,它使用 Rails 以外的东西(例如我们旧的基于 PHP 的方法),但访问与前端相同的数据库

B. Rails Metal:使用 Rails Metal/Rack 绕过 Rails 路由机制,但将 api 调用响应程序保留在 Rails 应用程序中

我的主要问题:

  1. Rails/Metal 是解决此类问题的合理方法吗?

但是也...

  1. 加载 Rails 环境的开销会不会还是太重?
  2. 有没有办法通过 Rails 更接近金属,绕过大部分环境?
  3. Rails/Metal 的性能是否会接近直接 PHP 的类似任务的性能(只是在这里寻找球场)?

和...

  1. 有没有比 A 和 B 都好得多的“C”选项?也就是说,在将 C 代码编译为二进制并作为 nginx 或 apache 模块安装之前的一些东西?

提前感谢您的任何见解。

4

3 回答 3

3

不是最详尽的答案,但是:

我不会为此使用金属,而是使用页面缓存。这样,请求将由网络服务器提供,根本没有动态语言。创建资源时清除相应的index页面。一个非常基本的例子是:

class PostsController < ApplicationController
  caches_page :index

  def index
    @posts = Post.all
    respond_to do |format|
      format.html
      format.xml
    end
  end

  def create
    @post = Post.new(params[:post])
    respond_to do |format|
      if @post.save
        expire_page :action => :index
        format.html { redirect_to posts_path }
        format.xml
      else
        format.html { render :action => "new" }
      end
    end
  end
end

有关更多信息,请阅读缓存指南

于 2010-04-10T04:38:35.467 回答
2

PHP 在每个请求上加载整个环境。在生产模式下,Rails 在服务器启动时加载整个环境。在正常的控制器动作调用期间肯定有相当多的 Ruby 代码正在执行。但是,在生产模式下,这些代码都与加载环境无关。并且使用 Rails Metal 而不是通常的 Rails 控制器堆栈删除了许多这些层,从而为每个请求节省了几毫秒的额外时间。

于 2010-04-10T05:01:23.123 回答
2

如果我确定了遇到任何性能问题的确切原因,我只会开始将功能下拉到 Rack/Metal。特别是在最新版本的 Rails(尤其是 3)和 Ruby 中,堆栈本身很少成为瓶颈。开始衡量,获得一些真实的指标并明智地优化。

我的经验法则:如果你没有指标,你就无法智能地推理你的性能问题和任何可能的解决方案。

根据我的经验,问题几乎总是:视图和数据库。

正如 Ryan 所建议的那样,缓存可以非常有效……您甚至可以移动您的架构以在 Rails 请求堆栈前使用反向代理来提供更多功能。像 Varnish 这样的缓存提供了令人难以置信的高性能。Rails 内置了对 etag 和 HTTP 标头的支持,以促进反向代理解决方案。

另一件事是查看 db 层本身。缓存在这里可以发挥很大的作用,但一些优化在这里也可能有用。确保明智地使用 Active Record 的 :include 是避免 N+1 查询情况的重要一步,但是 Rails 提供了极好的支持,可以将 memcached 放入堆栈中,只需很少或没有配置,这可以提供出色的性能提升。

于 2010-04-11T01:47:33.647 回答