Что делает время отклика героки слишком медленным - PullRequest
1 голос
/ 12 января 2020

Я подаю заявку на рельсы, чтобы сканировать информацию о рейсе с указанного c веб-сайта. Это приложение можно найти здесь https://vemaybay.herokuapp.com/. Локальное реагирование заняло всего 4-5 секунд, но при работе на героку - 15-20 секунд. Есть ли способ ускорить это время отклика? Я уже изменил тип бесплатного хобби-динамо, чтобы избежать затрат на раскрутку БД, но я считаю, что соединение с БД и запрос не являются причиной root. Это связано с проблемой хостинга? Поэтому можно подумать о покупке хоста.

Ниже приведен пример кода:

FlightService

 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

end

Затем в моем контроллере я просто звоню метод сканирования для извлечения данных:

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

1 Ответ

2 голосов
/ 12 января 2020

Я бы попытался добавить дополнение NewReli c Heroku, оно покажет вам, что занимает больше всего времени, скорее всего, это будет ваш код Ruby, выполняющий HTTP-запросы в действии контроллера для сканирования страницы.

Heroku работает медленнее, чем запуск кода на вашей собственной машине для разработки, поскольку ресурсы Heroku распределяются между пользователями, если вы не купили дорогие M / L dynos.

Если вы не поделитесь кодом для сканирования, мы не сможем Не знаю много, как это работает и где узкое место. Вы сканируете одну или несколько страниц (тогда это может быть медленным).

Вы можете попробовать переместить логи сканирования c в фоновый рабочий, например, использовать гем Sidekiq. Вы можете время от времени сканировать страницу и сохранять результаты в своей БД, тогда действие вашего контроллера будет запрашивать только данные из вашей БД, а не обходить страницу каждый раз. Вы также можете использовать грабли каждые 10 минут, определенные в Heroku Scheduler, чтобы сканировать страницу вместо Sidekiq (это может быть быстрее). Я не знаю, достаточно ли обновлять данные каждые 10 минут для вашего случая использования. Вам нужно выбрать техническое решение для нужд вашего бизнеса. С Sidekiq вы можете запускать задания чаще, запуская их каждую минуту, используя часовой механизм.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...