天道酬勤,学无止境

如何在 Ruby on Rails 中分析请求?(How can I profile a request in Ruby on Rails?)

问题

如何分析控制器操作?

我的一个观点需要相当长的时间来渲染,我想把它分解一下。 我看到了script/performance/profiler ,但这似乎只能访问全局范围。

回答1

ruby-prof 是要走的路。 这是一个操作方法,如何使用 ruby​​-prof 分析您的 Rails 和 Ruby 应用程序

如果将其与 kcachegrind 等可视化工具结合使用,则可以轻松地将应用程序代码与框架代码分开。

不久前,我在我当地的 Ruby 用户组中就这些工具进行了一次演讲:使用 ruby​​-prof 和 kcachegrind 使您的 rails 应用程序发挥作用

回答2

Ruby on Rails 控制台应该会显示哪些部分需要一段时间才能呈现。 如果这还不够,您可以安装新的 relic gem (https://github.com/newrelic/rpm) 并在开发人员模式下使用它,这将使您大致了解正在发生的事情。

如果您在 Heroku 上进行部署,您可以添加 rpm 的免费版本,这将为您提供有关正在运行的应用程序的相同统计信息。

Ruby 有一个分析器 (http://ruby-prof.rubyforge.org/),可以显示内存使用情况、调用次数等,但可能很难从框架代码中传播您的代码。

回答3

我在 https://github.com/bhb/rack-perftools_profiler 上取得了一些成功

它可以让您分析对任何 cputime、方法、对象分配或 walltime 的单个或多个请求,并通过 Rack 中间件很好地集成。

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 分析 rails 控制器操作(Profile a rails controller action)
    问题 在 Ruby on Rails 中分析控制器操作的最佳方法是什么。 目前,我正在使用蛮力方法,在我认为会成为瓶颈的地方之间puts Time.now调用。 但那感觉真的,真的很脏。 必须有更好的方法。 回答1 我不久前学习了这项技术,并发现它非常方便。 当它就位时,您可以将?profile=true添加到访问控制器的任何 URL。 您的操作将照常运行,但它不会将呈现的页面传送到浏览器,而是发送一个详细的、格式良好的 ruby​​-prof 页面,显示您的操作所花费的时间。 首先,将 ruby​​-prof 添加到您的 Gemfile 中,可能在开发组中: group :development do gem "ruby-prof" end 然后在 ApplicationController 中添加一个 around 过滤器: around_action :performance_profile if Rails.env == 'development' def performance_profile if params[:profile] && result = RubyProf.profile { yield } out = StringIO.new RubyProf::GraphHtmlPrinter.new(result).print out, :min_percent
  • 如何在ASP.NET MVC应用程序中分析请求的性能?(How to analyze the performance of requests in ASP.NET MVC application?)
    问题 我想捕获ASP.NET MVC应用程序中的命中时间,处理时间,内存消耗和请求的响应时间。 有什么方法或工具可以执行此操作吗? 回答1 检查由stackoverflow团队开发的miniprofiler http://code.google.com/p/mvc-mini-profiler/ 这可以帮助您进行一些分析。 有一个可用的nuget pacakge,可用于将其添加到项目中。 斯科特(Scott)写了一篇有关如何使用它的文章。 您也可以查看Glimpse。 有一些商业产品可以进行内存和性能分析,例如telerik just trace。 您可以下载其试用版并使用 回答2 您可以创建自己的小性能测试监视器。 这摘自Steven Sanderson的书《 Pro Asp.Net MVC 2 Framework》的第670页: public class PerformanceMonitorModule : IHttpModule { public void Dispose() { /* Nothing to do */ } public void Init(HttpApplication context) { context.PreRequestHandlerExecute += delegate(object sender, EventArgs e) {
  • 如何使用Ruby on Rails将数据从控制器传递到模型?(How do you pass data from a controller to a model with Ruby on Rails?)
    问题 您如何将数据从控制器传递到模型? 在我的application_controller我获取用户的位置(州和城市),并包含一个before_filter以使其通过以下方式在我的所有控制器中均可使用 before_filter :community def community @city = request.location.city @state = request.location.state @community = @city+@state end 然后,我尝试通过以下方式将在控制器中检索到的数据添加到模型中: before_save :add_community def add_community self.community = @community end 但是,数据永远不会从控制器传递到模型。 如果我使用: def add_community @city = request.location.city @state = request.location.state @community = @city+@state self.community = @community end 方法request.location.city和request.location.state在该模型中不起作用。 我知道其他所有东西都在工作,因为如果我在def_community下将
  • 如何在Ruby on Rails中获得当前的绝对URL?(How do I get the current absolute URL in Ruby on Rails?)
    问题 如何在Ruby on Rails视图中获取当前的绝对URL ? request.request_uri只返回相对URL 。 回答1 对于Rails 3.2或Rails 4+ 您应该使用request.original_url来获取当前URL。 此方法记录在original_url方法中,但是如果您很好奇,则实现为: def original_url base_url + original_fullpath end 对于Rails 3: 您可以编写"#{request.protocol}#{request.host_with_port}#{request.fullpath}" ,因为request.url现在已被弃用。 对于Rails 2: 您可以编写request.url而不是request.request_uri 。 这将协议(通常为http://)与主机,以及request_uri结合在一起,为您提供完整的地址。 回答2 我认为Ruby on Rails 3.0方法现在是request.fullpath 。 回答3 您可以使用url_for(only_path: false) 回答4 弃用警告:不建议使用#request_uri。 请改用fullpath。 回答5 如果您使用的是Rails 3.2或Rails 4 ,则应使用request.original
  • 如何使用Ruby on Rails发出HTTP请求?(How to make a HTTP request using Ruby on Rails?)
    问题 我想从另一个网站获取信息。 因此,(也许)我应该向该网站发出请求(在我的情况下为HTTP GET请求)并接收响应。 如何在Ruby on Rails中做到这一点? 如果有可能,是否可以在我的控制器中使用正确的方法? 回答1 您可以使用Ruby的Net :: HTTP类: require 'net/http' url = URI.parse('http://www.example.com/index.html') req = Net::HTTP::Get.new(url.to_s) res = Net::HTTP.start(url.host, url.port) {|http| http.request(req) } puts res.body 回答2 Net :: HTTP是Ruby内置的,但让我们面对现实吧,通常不使用繁琐的1980年代样式并尝试更高级别的替代方法通常会更容易: HTTP宝石 HTTParty RestClient 埃克斯孔 Feedjira(仅适用于RSS) 回答3 OpenURI是最好的; 就这么简单 require 'open-uri' response = open('http://example.com').read 回答4 require 'net/http' result = Net::HTTP.get(URI.parse('http:/
  • 如何在Ruby on Rails的控制台中调用控制器/视图帮助器方法?(How can I call controller/view helper methods from the console in Ruby on Rails?)
    问题 加载script/console ,有时我想玩控制器或视图帮助器方法的输出。 有什么方法可以: 模拟一个请求? 在请求中从控制器实例调用方法? 测试助手方法,是通过所述控制器实例还是其他方式? 回答1 要调用助手,请使用helper对象: $ ./script/console >> helper.number_to_currency('123.45') => "R$ 123,45" 如果您要使用默认情况下不包含的帮助程序(例如,因为您从ApplicationController删除了helper :all ),则只需包含该帮助程序即可。 >> include BogusHelper >> helper.bogus => "bogus output" 至于与控制器打交道,我引用了尼克的回答: > app.get '/posts/1' > response = app.response # you now have a rails response object much like the integration tests > response.body # get you the HTML > response.cookies # hash of the cookies # etc, etc 回答2 从脚本/控制台调用控制器动作并查看/操纵响应对象的简单方法是: > app
  • 限制对 Ruby on Rails API 的请求(Throttling requests to a Ruby on Rails API)
    问题 尝试在 Google 周围寻找一个 Rails 插件,该插件将允许限制特定资源消耗的请求量。 Django 的活塞为此提供了一些开源代码。 是否有一些可用于 Rails 的开箱即用的东西,或者可以安全地假设查看 Piston 是如何做到的并将其作为 Rails 插件移植是可以工作的吗? 回答1 这里有一些机架中间件可以完成您所追求的任务:http://github.com/dambalah/api-throttling 这是关于该中间件开发的博客文章:http://blog.messagepub.com/2009/05/05/how-to-rack-middleware-for-api-throttling/ 回答2 Rack::Defense 是一个用于请求限制和过滤的机架中间件。 它易于设置,占用空间小,并且只有两个依赖项(机架和 redis)。 您几乎可以根据任何条件进行过滤:ip、api 令牌、用户名等。 下面是一个示例,您将如何以每个 IP 每分钟 20 个请求的最大速率限制路径/login POST 请求: Rack::Defense.setup do |config| config.throttle('login', 20, 60 * 1000) do |req| req.ip if req.path == '/login' && req.post? end
  • 检查为什么Ruby脚本挂起(Check why ruby script hangs)
    问题 有时我的规格可能会挂起,并且我必须取消相应的红宝石过程。 当我运行使用capybara和webkit驱动程序编写的集成规范时,这很常见。 是否可以检查给定红宝石的工艺,并查看其悬挂位置? 哪种方法,操作,文件,行号等 回答1 tl; dr 使用gdb (例如Linux): echo 'call (void)rb_backtrace()' | gdb -p $(pgrep -f ruby) 或使用lldb (例如OS X): echo 'call (void)rb_backtrace()' | lldb -p $(pgrep -f ruby) 您可以使用调试库来调试Ruby脚本。 如果脚本是从外壳执行的,则可以通过将脚本的第一行(shebang)更改为: #!/usr/bin/env ruby -rdebug 或将其运行为: ruby -rdebug my_script.rb 加载调试器后,您可以设置一些断点,也可以通过键入c继续运行应用程序。 然后,调试器会根据任何异常(例如Ctrl + C )或断点(例如,组成debugger的行)自动中断。 然后,每当显示调试器控制台时,您都可以在以下选项之间进行选择: c表示“继续”(到下一个异常,断点或以下行: debugger ), n代表下一行, w / where显示框架/调用堆栈, l显示当前代码, cat来显示重点。
  • Ruby on rails:如何从登录弹出窗口向 rails 控制器发送 AJAX 请求以及用户给定的凭据(Ruby on rails: How to send an AJAX request to rails controller from login popup along with user given credentials)
    问题 此外,如何使用在弹出窗口中输入的值,在 javascript 函数中:单击时调用的login_request() ,最终将发送 AJAX 请求。 注意:代码片段包括弹出窗口中包含的所有字段。 <input class="csrf-token" type="hidden" name="authenticity_token" value=""> <div class="form-row clearfix"> <label class="lbl-fld">Email ID</label> <input type="email" name="user[email]" ng-model="loginForm.email" placeholder="me@example.com" ng-required="true"/> <!--<span class="valid-chk">--> <!--<i ng-class="{'false':'icon-close', 'true': 'icon-correct'}[form['user[email]'].$valid]"></i>--> <!--</span>--> </div> <div class="form-row clearfix"> <label class="lbl-fld">PASSWORD</label> <input
  • 如何在Ruby On Rails中重定向到上一页?(How to redirect to previous page in Ruby On Rails?)
    问题 我有一个页面,列出了所有具有可排序标题和分页的项目。 path: /projects?order=asc&page=3&sort=code 我选择编辑其中一个项目 path: projects/436/edit 当我单击该页面上的“保存”时,它将调用项目控制器/更新方法。 更新代码后,我想重定向到单击编辑特定项目之前的路径。 换句话说,我想在同一页面上进行相同的排序。 我看到了link_to(:back)并认为:back可以在redirect_to(:back)中工作,但这是不行的。 puts YAML::dump(:back) yields the following: :back 关于如何使它起作用的任何想法。 看来这个问题很容易解决,但是我对RoR还是陌生的。 回答1 在您的编辑操作中,将请求的URL存储在会话哈希中,该URL可在多个请求中使用: session[:return_to] ||= request.referer 保存成功后,然后在更新操作中重定向到它: redirect_to session.delete(:return_to) 回答2 为什么redirect_to(:back)对您不起作用,为什么不行? redirect_to(:back)对我来说就像一种魅力。 这只是redirect_to(request.env['HTTP_REFERER'])的捷径
  • Ruby on Rails:我可以将请求直接路由到视图吗?(Ruby on Rails: Can I route a request directly to a view?)
    问题 我有一个管理部分,它有一个controllers目录的子目录。 即,目录app/controllers/admin/包含一组文件,每个文件包含一个控制器,用于处理管理部分的单独部分。 现在,我想创建一个非常简单的“管理主页”,它只是说“欢迎来到管理部分”,但我想避免为此目的创建整个控制器,或者为这个视图在其他一些任意控制器中。 所以,问题是,有没有办法“直接路由到视图”——直接路由到 HTML 文件? (而且,我不想从/some-file.html之类的请求路径路由到 HTML 文件;我需要从/admin/类的路径路由。) 在这里问这个问题几乎不值得花时间创建存根控制器,但我相信我将来会再次有这样的需求。 回答1 不,你不能。 为什么? 设计:这只是违反了 Rails 强制您使用的 MVC 模式,这是为了您自己的利益。 总是有一个控制器参与。 是的,即使对于这样的存根页面,也需要一个控制器。 无论如何,几行代码不会伤害您,当您需要执行一些访问控制时,您会再次爱上它。 希望回答你的问题:-) 回答2 就像 moritz 所说,你不能完全绕过控制器,但你不一定要为这个动作创建一个完整的控制器。 当我需要“仪表板”或“登陆”类型的页面时,我只需将操作添加到我的 ApplicationController 中: class ApplicationController <
  • ruby rails - 重定向到原始请求 url(ruby rails - redirect to original request url)
    问题 这是我用于重定向到默认 url(myapp_url) 的内容。 但是我想更改重定向以转到用户在身份验证后输入的请求 url。 我怎么做? 我在这里搜索时尝试了几个选项,例如:back。 但是不行。 用户输入一个url,如果没有通过身份验证,则被重定向到登录页面,然后登录用户将被重定向到原始请求url。 def create user = User.Authenticate(params[:user_id], params[:password]) if user session[:user_id] = user.id redirect_to myapp_url, :notice => "Logged in!" else flash.now.alert = "Invalid email or password" render "new" end end 回答1 您可以阅读 Michael Hartl 撰写的“Ruby on Rails 教程”中关于“友好转发”的章节,了解如何轻松实现它。 基本上你有 3 个辅助方法: store_location在会话中存储用户所需的位置 redirect_back_or(url)将用户重定向到会话中存储的位置,如果未设置,则重定向到url方法参数中包含的位置和clear_return_to被redirect_back_or方法“内部
  • 如何在每个动作的基础上禁用Ruby on Rails的日志记录?(How can I disable logging in Ruby on Rails on a per-action basis?)
    问题 我有一个Rails应用程序,该应用程序的动作在开发时经常被频繁调用,以至于带来不便,因为它会导致很多我不关心的额外日志输出。 我如何才能使Rails仅为此一项操作就不记录任何内容(控制器,操作,参数,组合时间等)? 我也想在RAILS_ENV上对其进行条件化,因此生产日志已经完成。 谢谢! 回答1 您可以使Rails记录器对象静音: def action Rails.logger.silence do # Things within this block will not be logged... end end 回答2 使用lograge宝石。 宝石文件: gem 'lograge' config / application.rb: config.lograge.enabled = true config.lograge.ignore_actions = ['StatusController#nginx', ...] 回答3 以下至少适用于Rails 3.1.0: 制作一个可以静音的自定义记录器: # selective_logger.rb class SelectiveLogger < Rails::Rack::Logger def initialize app, opts = {} @app = app @opts = opts @opts[:silenced] ||=
  • Ruby on Rails:如何使用OAuth2 :: AccessToken.post?(Ruby on Rails: how to use OAuth2::AccessToken.post?)
    问题 OAuth2 :: AccessToken.post()方法在文档中指定如下: (对象)发布(路径,opts = {},&block) 我正在尝试传递一些参数,但似乎我做错了: response = token.post('/oauth/create.js', {:title => "title", :description => "desc"}) 参数永远不会到达方法,值始终为零。 那么,将post方法与参数一起使用的正确方法是什么? 那是什么? 我也收到警告:无法验证CSRF令牌的真实性。 这也可能是导致问题的原因。 情况是我从应用程序外部使用OAuth api。 OAuth 2是通过Doorkeeper gem实现的。 更新:我定义了作用域后,CSRF警告现在消失了。 另外,我还通过在URL中提供了“?title = test&...”作为参数来使用带有参数的post()方法。 仍然很高兴知道如何使用已记录的方法。 回答1 POST或PUT中的主体可通过选项主体参数进行访问。 对此没有任何文档。 必须查看oauth客户端代码本身才能发现这一点: https://github.com/intridea/oauth2/blob/ebe4be038ec14b3496827d29cb224235e1c9f468/lib/oauth2/client.rb 您的示例(具有正确的正文
  • Ruby on Rails Server选项[关闭](Ruby on Rails Server options [closed])
    问题 从目前的情况来看,这个问题不适合我们的问答形式。 我们希望答案得到事实,参考或专业知识的支持,但是这个问题可能会引起辩论,争论,民意测验或进一步的讨论。 如果您认为此问题可以解决并且可以重新提出,请访问帮助中心以获取指导。 8年前关闭。 为我的Ruby on Rails应用程序设置开发服务器的整个问题使我感到困惑。 我敢肯定,有WEBrick,Mongrel,Passenger,Apache,Nginx等等,我真的不了解他们扮演的不同角色。 我开始使用WEBrick,现在使用Mongrel进行开发。 这些服务器是独立的,还是位于Apache的前面? 我已经阅读了有关Passenger的文章,但我并不十分了解它的含义,该网站说“使Ruby Web应用程序的部署变得轻而易举”,它是否可以代替Mongrel? 就像Capistrano一样,它也可以部署Web应用程序吗? 请记住,我想测试SSL,并且我认为mongrel不支持SSL,最好的开发服务器设置是什么? 谢谢 回答1 取决于上下文,“部署”一词可以有两种含义。 您还将混淆Apache / Nginx的角色与其他组件的角色。 历史注释:本文最初写于2010年11月6日,当时Ruby应用服务器生态系统受到限制。 我已于2013年3月15日使用生态系统中的所有最新更新对本文进行了更新。 免责声明:我是Phusion
  • 在Rails中分配/替换参数哈希(assign/replace params hash in rails)
    问题 我在Rails控制器操作中具有以下代码序列。 如预期的那样,在IF之前,params包含请求参数。 在此之后,params为零。 谁能解释一下这是怎么回事? if false params = {:user => {:name => "user", :comment => 'comment'}} end 谢谢你。 回答1 所述params其中包含请求参数实际上是一个方法调用,它返回一个包含参数的散列。 您的params =行正在分配给名为params的局部变量。 在if false块之后,Ruby看到了local params变量,因此当您稍后在方法中引用params ,本地变量优先于调用相同名称的方法。 但是,因为您的params =赋值位于if false块内,所以永远不会为该局部变量赋值,因此该局部变量为nil 。 如果尝试在分配给本地变量之前先引用它,则会得到一个NameError: irb(main):001:0> baz NameError: undefined local variable or method `baz' for main:Object from (irb):1 但是,如果对变量的分配不在代码执行路径中,则Ruby创建了局部变量,但其值为nil 。 irb(main):007:0> baz = "Example" if false => nil
  • 在 Ruby on Rails 中仅接受 HTTPS 请求(Accept only HTTPS requests in Ruby on Rails)
    问题 对于某些操作,我只想接受 HTTPS 请求。 这是我的第一个代码,但我认为有更好的方法。 before_filter :reject_http_request, :only => [:fucntion_a, :function_b] def reject_http_request scheme = request.protocol.to_s.downcase if scheme == 'http://' raise AccessDeniedException.new("Not allowed protocol scheme") end true end 如何改进此代码? 回答1 您可以使用 rack-ssl-enforcer gem 在 Rack 级别执行此操作。 它可配置为允许排除特定路径、主机和方法。 如果它满足您的需求,我建议您这样做而不是滚动您自己的解决方案。 我们目前在生产中使用它,效果很好。 回答2 要为特定操作强制使用 SSL,您可以使用 force_ssl。 对于整个应用程序,您只需在您的environment.rb文件中执行以下操作: config.force_ssl = true 。 在这里阅读更多。
  • Ruby on Rails将对数组进行分页(Ruby on Rails will_paginate an array)
    问题 我想知道是否有人可以解释如何在对象数组上使用will_paginate? 例如,在我的网站上,我有一个“意见”部分,用户可以在其中对意见进行评分。 这是我编写的一种方法,用于收集对意见进行评分的用户: def agree_list list = OpinionRating.find_all_by_opinion_id(params[:id]) @agree_list = [] list.each do |r| user = Profile.find(r.profile_id) @agree_list << user end end 谢谢 回答1 will_paginate 3.0旨在利用Rails 3中新的ActiveRecord::Relation ,因此默认情况下它仅在关系上定义paginate 。 它仍然可以与数组一起使用,但是您必须告诉rails需要该部分。 在您的config/initializers文件中(我使用will_paginate_array_fix.rb ),添加此文件 require 'will_paginate/array' 然后您可以在数组上使用 my_array.paginate(:page => x, :per_page => y) 回答2 您可以使用Array#from来模拟分页,但是这里的真正问题是您根本不应该使用Array 。
  • 如何在Ruby on Rails的form_for中使用hidden_​​field?(How do I use hidden_field in a form_for in Ruby on Rails?)
    问题 我已经读过这篇文章,但是我对RoR还是陌生的,因此在理解它时遇到了一些麻烦。 我正在使用表单创建新的请求记录,并且我需要发送的所有变量已经存在。 这是我需要发送的数据(在do循环中): :user_id => w[:requesteeID] :requesteeName => current_user.name :requesteeEmail => current_user.email :info => e 这是我的表格,目前可以使用,但仅对所有内容发送NULL值: <% form_for(:request, :url => requests_path) do |f| %> <div class="actions"> <%= f.submit e %> </div> <% end %> 如何使用hidden_​​fields发送已经拥有的数据? 谢谢阅读。 回答1 引用hidden_​​field或hidden_​​field_tag <% form_for(:request, :url => requests_path) do |f| %> <div class="actions"> <%= f.hidden_field :some_column %> <%= hidden_field_tag 'selected', 'none' %> <%= f.submit e %>
  • 与 MRI Ruby 的并发请求(Concurrent requests with MRI Ruby)
    问题 我整理了一个简单的例子,试图使用一个基本的例子来证明 Rails 中的并发请求。 请注意,我使用的是 MRI Ruby2 和 Rails 4.2。 def api_call sleep(10) render :json => "done" end 然后我在我的 Mac(I7 / 4 Core)上的 Chrome 中访问 4 个不同的选项卡,看看它们是串行还是并行运行(真正并发,这很接近但不是一回事)。 即,http://localhost:3000/api_call 我无法使用 Puma、Thin 或 Unicorn 使其工作。 每个请求都是连续出现的。 10 秒后的第一个标签,20 秒后的第二个(因为它必须等待第一个完成),之后的第三个...... 根据我的阅读,我相信以下内容是正确的(请纠正我)并且是我的结果: Unicorn 是多进程的,我的示例应该可以工作(在 unicorn.rb 配置文件中定义工作人员数量之后),但它没有。 我可以看到 4 个工人开始,但一切都在串联。 我正在使用 unicorn-rails gem,使用 unicorn -c config/unicorn.rb 启动 rails,在我的 unicorn.rb 中我有: -- 独角兽.rb worker_processes 4 preload_app true timeout 30 listen