Опыт Разработки Сервис-Ориентированной Системы

Некоторое время назад вместе с небольшой командой программистов мы начали разработку довольно интересного с технической точки зрения аналитического проекта.

Его основной целью была обработка данных, полученных с различных веб-страниц.

Необходимо было эти данные обработать в удобную форму и затем проанализировать собранную статистику.

Пока у нас не было большого количества всевозможных данных, у нас не возникало нестандартных задач и все решения были достаточно простыми.

Но проект рос, и объем собираемой информации, хотя и не очень быстро поначалу, все же увеличивался.

Кодовая база также выросла.

И через некоторое время мы осознали очень печальный факт — из-за всяких костылей и быстрых исправлений мы нарушили практически все возможные принципы проектирования.

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

После обсуждения и размышлений было решено, что для наших целей архитектура парсинга Интернета должна быть в первую очередь сервис-ориентированной (SOA).

Далее мы отталкивались от этого подхода и выделили три основные части будущей системы, отвечающие за следующие задачи:

  1. Получение содержимого страницы, данных от различных сервисов через API, данных из структурированных файлов.

  2. Структурирование полученной информации
  3. Анализ статистики и создание рекомендаций
В результате такого разделения должно было получиться три независимых сервиса: Fetch Service, Parse Service и Analysis Service. *Здесь и далее я буду использовать некоторые английские названия для большего удобства восприятия и краткости.

Далее встал вопрос о том, как эти сервисы будут взаимодействовать друг с другом.

При определении общего механизма было решено использовать концепцию конвейерной обработки.

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

В качестве коммуникационной шины был выбран механизм организации массового обслуживания на базе RabbitMQ.

Опыт разработки сервис-ориентированной системы

Итак, мы определились с основной архитектурной моделью.

Оно оказалось довольно простым, понятным и вполне расширяемым.

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



Сервисные компоненты и технологии
Давайте немного поговорим о технологиях, которые используются внутри каждого отдельного сервиса.

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

Ниже я опишу общие моменты, а точнее основные составляющие.

Всего их четыре.

Первый — модуль обработки данных, содержащий всю основную логику работы с данными.

Это набор работников, выполняющих задачи.

И клиенты, которые создают эти задачи.

Здесь Gearman используется в качестве сервера задач и, соответственно, его API. Сами работники и клиенты — это отдельные процессы, которые контролируются с помощью Supervisord. Следующий компонент — хранилище результатов.

Это база данных в MongoDB. По сути, данные извлекаются с веб-страниц или через различные API, которые возвращают JSON. А MongoDB весьма удобна для хранения такого рода информации.

Кроме того, может измениться структура результатов, появиться новые метрики и т. д. И в этом случае мы легко можем внести изменения в структуру документа.

И, наконец, третий компонент системы — очереди.

Есть два типа очередей.

Первые занимаются тем, что служат для передачи запросов к сервисам от других сервисов или от внешних клиентов (не путать с клиентами Gearman).

Такие очереди называются очередями запросов.

В случае с ранее упомянутой службой поиска контента (Fetch Service) строка JSON отправляется в очередь этого типа.

Он содержит URL нужной страницы или параметры для запроса к стороннему API. Второй тип очередей — очереди уведомлений.

В очередь такого типа сервисы помещают информацию об обработанных запросах и результат можно получить из хранилища.

Таким образом реализуется асинхронное выполнение запросов на получение, обработку и анализ данных.

В качестве брокера сообщений был выбран RabbitMQ. Это хорошее решение, оно прекрасно работает, хотя и с некоторыми проблемами.

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



Опыт разработки сервис-ориентированной системы



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

Далее я опишу процесс общения более подробно.

Есть два типа общения.

Внутри системы, между сервисами.

И между конечным клиентом и всей системой в целом.

Например, службе синтаксического анализа требуются новые данные.

Он отправляет запрос в очередь для Fetch Service, а затем продолжает заниматься своими делами — запросы выполняются асинхронно.

После того как служба Fetch получит запрос из очереди, она выполнит необходимые действия для получения данных из нужного источника (веб-страницы, файла, API) и размещения их в хранилище (MongoDB).

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



Опыт разработки сервис-ориентированной системы



Служба получения
И напоследок расскажу еще немного о сервисе, отвечающем за получение исходных данных из внешних источников.

Эта основная часть системы является первым этапом конвейера обработки данных.

На него возлагается ответственность за решение следующих задач:

  1. Получение данных из внешнего источника
  2. Обработка исключений и ошибок на этом этапе (например, обработка HTTP-ответов)
  3. Предоставление основной информации о полученных данных (заголовки, статистика изменения файлов и т.д.)
Само извлечение исходных данных является важной частью большинства систем, где осуществляется структурирование данных.

И сервис-ориентированный подход в этом случае очень удобен.

Мы просто говорим: «Дайте мне эти данные» и получаем желаемое.

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

Вы можете использовать разные API с разными форматами и протоколами.

Вся логика получения целевых данных изолирована на этом уровне.

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

Пожалуй, я закончу здесь.

Конечно, есть много других аспектов разработки таких систем.

Но главное помнить — всегда в первую очередь думать об архитектуре и использовать принцип единой ответственности.

Изолируйте компоненты системы и соединяйте их простым и понятным способом.

И вы получите результат, который легко масштабировать, легко контролировать и очень просто использовать в дальнейшем.

Теги: #design #parsing #php #rabbitmq #mongodb #gearman #workers #php #Системный анализ и проектирование

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.