Pull to refresh

Архитектура сервиса сбора и классификации объявлений жилья из Вконтакте

PHPProgrammingSystem Analysis and DesignVK APIGo


В этой статье я расскажу о том, как устроен и развивался сервис по поиску объявлений жилья из Вконтакте, почему была выбрана сервис-ориентированная архитектура, а также какие технологии и решения использовались при его разработке.

Сервис работает более девяти месяцев.

За это время:

  • Удалось охватить 21 крупнейший город России. Среди них такие, как Москва, Санкт-Петербург, Екатеринбург и Казань.
  • Получилось увеличить общее число станций метро с 65 до 346.
  • Увеличилось среднее число объявлений с 131.2 до 519.41 в день.
  • Была добавлена панель управления настройками.
  • Были добавлены боты для Telegram и Вконтакте. Они автоматически уведомляют подписчиков о новых объявлениях.

Далее по тексту я буду использовать слово сервис — как модуль SOA, а не web сервис целиком.

Я выбрал SOA архитектуру, потому что она давала возможность:

  • Использовать разные технологии для решения разных задач.
  • Разрабатывать сервис независимо от других.
  • Деплоить сервисы независимо от других.
  • Горизонтально масштабировать сервисы.

Можно было бы назвать это микросервисной архитектурой, но имелись небольшие отличия. Между сервисами используется обмен данными на основе «Общей базы данных» по протоколу MDBWP вместо привычного для микросервисов HTTP API и хранения данных у каждого сервиса в своей БД. Такой подход был обусловлен быстротой разработки с возможностью сохранить все преимущества описанного SOA подхода.

Чтобы автоматизировать деплой, был выбран Ansible
Это одна из систем управления конфигурациями, которая имеет низкий порог вхождения.

В качестве базы данных была выбрана MongoDB. Эта документоориетированная БД отлично подходила для хранения объявлений с со списком станций метро, контактными данными арендодателей, а также описанием объявления.

На данный момент общая схема взаимодействия сервисов выглядит следующим образом:



Сервисы:




rent-view — сервис отображения объявлений и поиска по ним


github.com/mrsuh/rent-view



Сервис написан на NodeJS, т.к. самым важным критерием его качества была скорость ответа сервера пользователю.

Сервис обращается за объявлениями в MongoDB, рендерит HTML страницы с помощью шаблонизатора doT.js и отдает их браузеру.

Сервис собирается с помощью Grunt.

Для работы в браузере написаны скрипты на чистом JS, а стили на LESS. В качестве прокси сервера используется Nginx, который кеширует часть ответов и обеспечивает HTTPS соединение.

rent-collector — сервис сбора объявлений


github.com/mrsuh/rent-collector



Сервис собирает объявления, классифицирует их и записывает в БД.

Он написан на PHP по нескольким причинам: знание необходимых библиотек для написания сервиса, а также высокая скорость разработки.

Используется фреймворк Symfony 3.

В качестве сервиса очередей был выбран beanstalk. Он легковесный, но не имеет своего брокера сообщений. Это именно то, что нужно для небольшого виртуального сервера и для данных некритичных к утере.

С помощью beanstalk были сделаны 4 канала для обмена сообщениями:

  • parser — выделяет из текста такие факты, как тип объявления, цена, описание и ссылки. Чтобы ускорить обработку данных, я запустил несколько потребителей для этого канала.
    Примечание: потребитель общается с сервисом rent-parser.
  • collector — записывает обработанные данные о объявлениях в БД.
  • notifier — оповещает пользователей о новых объявлениях. Примечание: потребитель общается с сервисом rent-notifier.
  • publisher — публикует объявления в нескольких группах Вконтакте.

rent-parser — сервис классификации объявлений


github.com/mrsuh/rent-parser
Сервис написан на Golang.

Для извлечения структурированных данных из текста сервис использует парсер Tomita от Yandex. Осуществляет предварительную обработку текста и последующую обработку результатов парсинга.

Чтобы вы могли протестировать работу сервиса я сделал открытое API.

Попробовать парсер онлайн
Запрос:
curl -X POST -d 'сдаю двушку за 30 тыс в месяц. телефон + 7 999 999 9999' 'http://api.socrent.ru/parse'

Ответ:

{"type":2,"phone":["9999999999"],"price":30000}

Типы объявлений:
+ 0 — комната
+ 1 — 1 комнатная квартира
+ 2 — 2 комнатная квартира
+ 3 — 3 комнатная квартира
+ 4 — 4+ комнатная квартира
+ 5 — студия
+ 6 — не объявление

Более подробно о классификации объявлений я писал здесь habrahabr.ru/post/328282

rent-control — сервис управления настройками


github.com/mrsuh/rent-control



Он написан на PHP по нескольким причинам: знание необходимых библиотек для написания сервиса, а также высокая скорость разработки.
Используется фреймворк Symfony 3.
Библиотека стилей Bootstrap 3.

К настройкам, которыми управляет сервис, относятся:

  • объявления;
  • черный список;
  • конфигурации публикаций;
  • конфигурации парсинга.

Изначально все данные для управления парсингом лежали в конфигурационных файлах. С увеличением количества городов понадобилось их визуализировать и упростить редактирование записей. Кроме того, требовалось упростить добавление новых параметров.

rent-notifier — бот-сервис для рассылки новых объявлений в Telegram и Вконтакте.


github.com/mrsuh/rent-notifier

Пример подписки на объявления:



Сервис написан на Golang по причине критичности к скорости ответа пользователю.
Суть работы сервиса в следующем: вы подписываетесь на рассылку новых объявлений, а по мере добавления бот присылает вам о них сообщения. В текст сообщения сервис вставляет ссылку на оригинальное объявление.

Вспомогательные репо




Код для общей базы данных на PHP


github.com/mrsuh/rent-schema

Схема общей базы данных:



С добавлением сервиса rent-control появилось дублирование кода схем БД. Поэтому было принято решение вынести код в отдельный пакет. Теперь для любого сервиса на PHP достаточно добавить в зависимости этот пакет через composer.

composer require mrsuh/rent-schema


ODM для mongoDB


github.com/mrsuh/mongo-odm

Первой ODM для PHP MongoDB о которой я подумал была Doctrine 2. Она идет вместе с Symfony 3 и имеет хорошую документацию.

Но на момент написания сервиса, чтобы эта ODM начала работать с последней версией драйверов для Mongo PHP, необходимо было ставить еще один пакет в качестве прослойки между новым и старым API. Doctrine 2 сам по себе довольно большой проект, а с дополнительным пакетом становился еще больше. Вместо этого хотелось чего-то легковесного. Поэтому я решил сам написать ODM с минимальным функциональным набором. И у меня получилось — ODM полностью справляется со своими обязанностями.

Немного статистики




Сервис добавляет на сайт в среднем 519,41 объявлений в день.

Самыми популярными станциями метро, среди крупнейших городов России, оказались следующие:

  • Санкт-Петербург — Девяткино
  • Москва — Комсомольская
  • Казань — Проспект Победы
  • Екатеринбург — Уралмаш
  • Нижний Новгород — Автозаводская
  • Новосибирск — Площадь Маркса
  • Самара — Московская

Больше статистики можно посмотреть на самом сайте.

Заключение




Если вы еще не определились нужна ли вам SOA архитектура, то сделайте монолитное приложение с разбивкой на модули. Так будет проще перевести ваше приложение на сервисы при необходимости. Но если вы все-таки решите использовать SOA архитектуру, то должны понимать, что так может увеличиться сложность разработки, сложность деплоя, объем кода, а также объем сообщений между сервисами.

P.S. Последние две квартиры я нашел с помощью своего сервиса. Надеюсь, вам он тоже поможет.
Tags:SOAмикросервисыTomitaGolangPHPNodeJSBeanstalkMongoDBВконтакте
Hubs: PHP Programming System Analysis and Design VK API Go
Total votes 13: ↑12 and ↓1 +11
Views7.8K

Popular right now

Go (golang) Backend Developer
from 170,000 to 250,000 ₽ikitlabRemote job
Разработчик Golang / PHP (удаленно)
to 200,000 ₽IT and DigitalRemote job
Senior Control Plane Developer
from 3,600 to 4,700 $DataDirect Networks Inc. (DDN)Remote job
NodeJS разработчик (удаленно)
from 140,000 to 180,000 ₽КриптоштампRemote job
Golang разработчик
to 400,000 ₽KinddaRemote job