ruby-on-rails - 是什么让 heroku 响应时间太慢

标签 ruby-on-rails ruby heroku

我正在制作一个 Rails 应用程序来抓取来自特定网站的航类信息。这个应用程序可以在这里找到https://vemaybay.herokuapp.com/ . 本地响应只需要 4-5 秒左右,但在 heroku 上运行时需要 15-20 秒。 有没有办法加快这个响应时间? 我已经将 free 更改为 hobby dyno 类型以避免 DB 启动成本,但我相信 DB 连接和查询不是根本原因。 它与托管问题有关吗?所以可以考虑买个主机。

下面是我的示例代码:

飞行服务

 def crawl(from, to, date)
return if flight_not_available?(from, to)
begin
  selected_day = date.day - 1
  browser = ::Ferrum::Browser.new
  browser.headers.set({ "User-Agent" => "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36" })

  browser.goto("https://www.abay.vn/")
  browser.at_css("input#cphMain_ctl00_btnSearch").click
  browser.back

  browser.execute("document.getElementById('cphMain_ctl00_txtFrom').setAttribute('value','#{from}')")
  browser.execute("document.getElementById('cphMain_ctl00_txtTo').setAttribute('value','#{to}')")
  browser.execute("document.getElementById('cphMain_ctl00_cboDepartureDay').selectedIndex = #{selected_day}")
  browser.at_css("input#cphMain_ctl00_btnSearch").click
  # browser.execute("document.querySelectorAll('a.linkViewFlightDetail').forEach(btn=> btn.click())")
  sleep(1)
  body = Nokogiri::HTML(browser.body)

  flight_numbers = body.css("table.f-result > tbody > tr.i-result > td.f-number").map(&:text)
  depart_times = body.css("table.f-result > tbody > tr.i-result > td.f-time").map { |i| i.text.split(" - ").first }
  arrival_times = body.css("table.f-result > tbody > tr.i-result > td.f-time").map { |i| i.text.split(" - ").second }
  base_prices = body.css("table.f-result > tbody > tr.i-result > td.f-price").map(&:text)

  prices = base_prices
  store_flight(flight_numbers, from, to, date, depart_times, arrival_times, base_prices, prices)
  browser.quit
rescue StandardError => e
  Rails.logger.error e.message
  fail_with_message(e.message)
  browser.quit
end

结束

然后在我的 Controller 中调用 crawl 方法来获取数据:

service = FlightService.new(from: @from, to: @to, departure_date: @departure_date, return_date: @return_date)
service.crawl_go_flights
@go_flights = service.go_flights

最佳答案

我会尝试添加 NewRelic Heroku 附加组件,它会向您显示什么花费的时间最多,很可能是您的 Ruby 代码在 Controller 操作中执行 HTTP 请求以抓取页面。

Heroku 往往比在您自己的开发机器上运行代码要慢,因为 Heroku 资源是跨用户共享的,除非您购买了昂贵的 M/L dynos。

如果没有您分享抓取代码,我们就不知道它是如何工作的以及瓶颈在哪里。您是抓取单个页面还是多个页面(这可能会很慢)。

您可以尝试将抓取逻辑移至后台工作程序,例如,使用 Sidekiq gem。您可以不时地抓取页面并将结果存储在您的数据库中,然后您的 Controller 操作只会从您的数据库中请求数据,而不是每次都抓取页面。您还可以使用 Heroku Scheduler 中定义的每 10 分钟一次的 rake 任务来抓取页面而不是 Sidekiq(这样做可能会更快)。我不知道每 10 分钟更新一次数据是否足以满足您的用例。您需要为您的业务用例需求选择一个技术解决方案。使用 Sidekiq,您可以使用发条 gem 每 1 分钟启动一次作业,从而更频繁地运行作业。

关于ruby-on-rails - 是什么让 heroku 响应时间太慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59701832/

相关文章:

ruby-on-rails - 使用 Ruby on Rails 实现 angular.js 中的安全性

ruby-on-rails - 创建 Ruby On Rails 应用程序时出现 Webpacker 错误

ruby-on-rails - Bundler 找不到 gem mime 类型的兼容版本

python - Heroku 上的 Flask 有很多 500 错误,在开发机器上运行

ruby-on-rails - 在生产环境中使用 Capistrano 的 Rails 多环境凭证 : How to set it up?

ruby-on-rails - 未定义的方法 `close_connection_after_writing'

ruby-on-rails - 在 Rails 中使用 titleize 作为首字母缩略词

ruby - 我正在学习 Ruby,我不清楚 :* means in inject(:*) 是什么

ruby - 使用 ruby​​mine 调试 Rails 应用程序

ruby-on-rails - 在 Heroku 上的 Rails 应用程序中使用 Bootstrap 时出现 Sass::SyntaxError