В прошлом я написал несколько больших пауков и анализаторов страниц, и одну из вещей, о которых следует помнить, - какой код предоставляет какой сервис всему приложению.
Rails предоставляет представление данных, собираемых вашим паучьим движком. Презентация - это одна сторона медали, а паутинка - другая, и они должны представлять собой две отдельные кодовые базы, связанные каким-то механизмом обмена данными, который, в вашем случае, является базой данных. База данных дает вам огромные преимущества, как и наличие Rails, когда ваш код-паук отдельный. Похоже, у вас уже есть какое-то разделение, но я бы порекомендовал создать более широкий разрыв. Имея это в виду, вот как я это делал раньше, и что я буду делать сейчас.
Раньше у меня было отдельное приложение для моего паука, которое порождало несколько задач с пауками. Каждая задача будет просматривать несколько разных URL-адресов, выдавать результаты в базу данных и затем завершать работу. Каждый раз при выходе из основного приложения появляется другой паук для обработки большего количества URL. В каждом цикле основное приложение проверяло файл конфигурации YAML на наличие параметров времени выполнения, таких как количество подзадач, которые он должен выполнить, сколько URL-адресов они получат, сколько времени они ожидают подключения и т. Д. дата последней модификации файла конфигурации каждый раз, когда он загружал его, поэтому, если я внесу изменение в файл, приложение обнаружит его в течение достаточно короткого времени, перечитает файл и отрегулирует его поведение.
Вся информация о состоянии URL-адресов / страниц / сайтов, которые были просмотрены / скопированы, была сохранена в базе данных, чтобы я мог проверить ее ход. Я мог видеть, сколько было обработано или осталось в очереди, различные коды результатов и возвращаемое содержимое. Если мне что-то не нравилось, я мог бы даже настроить фильтры, чтобы пропустить ненужные страницы, зная, что задачи-пауки будут обновлены через несколько минут.
Эта система работала очень хорошо, без проблем пропустила серию веб-сайтов основных клиентов, работая несколько недель, пока я добавляла новые сайты в список. (Мы помогали одной из компаний из списка Fortune 50 улучшить свои сайты, и каждый сайт был разработан и внедрен другой группой, что делало каждый сайт совершенно другим. Мой код должен был быть гибким и надежным; я был очень доволен тем, как он работал вне.)
Чтобы изменить это, в наши дни я использовал бы таблицу базы данных для хранения всей информации о конфигурации. Таким образом, я мог бы легко создать форму администратора и позволить кому-то другому унаследовать задачу настройки конфигурации приложения. Задачи паука также должны быть написаны так, чтобы они извлекали свою конфигурацию из базы данных, а не наследовали ее из основного приложения. Первоначально у меня было основное приложение, которое выполняло все администрирование и передавало информацию о конфигурации приложениям-паукам, потому что я хотел, чтобы количество подключений к базе данных было как можно меньше. Я использовал Postgres и теперь знаю, что он мог легко справиться с нагрузкой, поэтому, позволив отдельным задачам управлять их конфигурацией, я мог бы сделать ее более отзывчивой.
Отделяя механизм паутинга от механизма представления, можно было временно остановить один или другой, не влияя на ход выполнения задания. После того, как у меня была автоперезагрузка префов, я не думаю, что мне пришлось останавливать двигатель паука, я просто отрегулировал его префы. Он буквально работал в течение нескольких недель без остановки, и мы в конечном итоге отключили его, потому что у нас было достаточно данных для наших нужд.
Итак, я бы порекомендовал настроить ваш код так, чтобы ваш движок-паук не зависел от Rails, вместо этого он запускается cron или отдельным приложением для планирования. Если вам придется временно остановить Rails, ваш двигатель все равно будет работать. Если вам нужно временно остановить двигатель, Rails может продолжить обслуживание страниц. База данных находится между двумя, выступая в качестве клея.
Конечно, если база данных выйдет из строя, вы будете все время крутиться, но что еще нового? : -)
РЕДАКТИРОВАТЬ: Крис сказал:
"Я понимаю вашу точку зрения по поводу разделения кода, хотя у меня Ruby-fu низкий - не уверен, насколько далеко я могу разделить вещи без необходимости иметь копии ActiveModel / миграции, плюс некоторые общие классы моделей".
Если мы посмотрим на ваше приложение как spider engine <--> | <-- database --> | <--> Rails/MVC/presentation
, где движок и Rails отдельно читают и записывают в базу данных, и смотрят, что у каждого хорошо получается, это помогает понять, какразбить их на отдельные кодовые базы.
Rails предназначен для обработки миграций, так что давайте.Нет причин изобретать это колесо.Но как часто вы делаете миграции, и на что это влияет?Вы делаете их редко, когда приложение стабильно, и в этот момент вы выполняете их в цикле обслуживания, чтобы настроить базу данных.Вы можете на несколько минут выключить механизм паука и веб-интерфейс, перенастроить базу данных, затем запустить и начать работу.Миграции - неизбежное зло, но едва ли они останавливаются, когда начинают работать.У большинства предприятий есть «Software Sunday», или какое-то предварительно объявленное окно обслуживания, поэтому сделайте то же самое.
ActiveRecord, моделирование и ассоциации также довольно легко справляются.Модели находятся в файле, который уже необходим Rails для внутреннего использования, поэтому механизм паутинга может наследовать ноу-хау базы данных таким же образом;Несколько приложений / скриптов могут использовать один и тот же файл модели.В книгах по Rails об этом много не говорится, но ActiveRecord на самом деле довольно прост в использовании вне Rails.Поищите в googles activerecord without rails
для получения дополнительной информации.
Вы можете включить ActiveSupport также, если вы хотите, чтобы некоторые из его расширений для классов выполнялись обычным образом require
, но логика «просмотра» и «контроллера» Rails, которая обычно применяется для представления веб-интерфейса, вообще не нужна в движке.
Бизнес-логика, которая используется в контроллерах в Railsможет даже быть реорганизован в отдельные методы, которые требуются стороной Rails и движком паука.Это другой взгляд на Rails, но он соответствует мантре «СУХОЙ» - не повторяйте себя, поэтому делайте вещи модульными и требуйте (или require_relative
) кусочков и кусочков, которые являются строительными блоками всей системы.
Если вам не нужна совершенно отдельная кодовая база, вы можете воспользоваться скриптом Rail runner
, который предоставляет скрипту доступ к ActiveRecord :: Base и ActiveRecord :: Associations и ActiveSupport.Сделайте rails runner -h
из главного каталога вашего приложения или найдите «rails runner
» для получения дополнительной информации.runner
не подходит для работы, которая запускается и выполняется много раз в час, потому что стоимость запуска Rail высока.Но если у вас есть долгосрочная задача, скажем, та, которая работает параллельно с вашим приложением rails, то это отличный выбор.Я бы серьезно отнесся к паучьей стороне вашей заявки.В конце концов вы можете захотеть отключить spidering-engine для отдельного хоста, чтобы на стороне презентации был выделенный хост, поэтому runner
поможет вам выиграть время и сделать это небольшими шагами.