我正在制作一个 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/