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

Меня зовут Василий Клюев, я — директор по разработке в облачном хранилище Platformcraft, и в этой статье расскажу, как мы построили надежную систему объектного хранения с различными инструментами для работы с медиаконтентом, а также почему мы выбрали Rust и Go.

От монолита к микросервисам: зачем вообще переходить?

Сначала чуточку о боли.

Мы создали собственное объектное хранилище в 2012 году для хранения большого объема медиафайлов. Распределенный монолит позволил нам быстро развернуть сервис и закрыть потребности небольшого количества заказчиков.

Система состояла из различных сервисов, каждый из которых выполнял определенную функцию, а связывала их единая база данных. То есть была апишка (собственный API), был storage (хранилище), два бэкэнда (сам веб-сервис), транкодер и между ними шарилась БД.

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

Transcoder — сервис транскодирования.

Транскодирование — процесс преобразования аудио/видео потоков внутри медиафайла или потока прямого вещания. Потоки декодируются, параметры видео или аудио преобразуются, а затем потоки повторно кодируются.

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

Такая модель была детищем хаоса, в простонародье называемым «распределенный монолит». Взаимосвязанные сервисы нужно было распутать и как можно скорее перейти на легкоуправляемые микросервисы.

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

Проектирование микросервисов: как мы начали распиливание монолита?

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

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

Микросервисная структура идеально подходила по следующим причинам:

  1. Ее легче обслуживать, обновлять и отлаживать отдельные сервисы.
  2. Можно масштабировать отдельные компоненты приложения без привязки к ресурсам.
  3. Больше возможностей для разработки инструментов с использованием различных технологий.
  4. Можно работать одновременно над разными сервисами, что ускоряет разработку.
  5. Высокая отказоустойчивость системы из-за изоляции ее служб.

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

Начали с разделения тесно связанных сервисов на независимые компоненты. Дальше внедрили новые сервисы с конкретными функциями. Например, создали службу «Garbage Collector» для удаления файлов и управления метаданными.

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

У нас появился новый дашборд, работающий с нашим новым API (Filespot), и мы перестали «ходить» в базу данных каждого сервиса. Теперь у всех сервисов появилась своя база, и при внесении изменений в один компонент, не нужно бегать и перезапускать каждый.

Таким образом все сервисы Platformcraft стали атомарными.

Создание экосистемы микросервисов для объектного хранилища

У нас специфический тип нагрузки из-за работы с файлами больших размеров. Поэтому нашей целью было разработать архитектуру, «переваривающую» большие медиафайлы, огромное количество метаданных и функций, сохраняя при этом высокую доступность и производительность.

Мы разделили обязанности между различными микросервисами (ведь шарить БД между сервисами — ну совсем дурной тон) и выделили:

  • API Gateway — служба действует как точка входа для клиентов (набор апишек). Внутри API Gateway создана доменная модель, помогающая настроить взаимодействие между микросервисами.
  • Garbage Collector — отдельно запускаемая служба для очистки хранилища (служба «ходит» по всем сервисам и удаляет объекты).
  • Profile — сервис работы с профилями пользователей (email, телефон и пр.).
  • Filespot — наша система хранения объектов, которая обеспечивает обработку контента, его хранение и извлечение.
  • IAM — служба управления доступом к ресурсам, отслеживающая, есть ли права у клиента на доступ к конкретному объекту.
  • API-шлюз — поддерживает единообразие интерфейса для клиентов.
  • Transcoder — сервис транскодирования. Сервис транскодирования в Platformcraft работает без привязки к другим сервисам системы. Взаимодействие происходит посредством API и системы обмена сообщениями Kafka.
  • Streamer — сервис потокового вещания, который позволяет создавать сетку вещания из заранее подготовленных медиафайлов, скомпонованных в блоки. Подготовка медиафайлов может быть осуществлена с помощью сервиса Transcoder с последующей загрузкой в Filespot.
  • Recorder — сервис записи медиа потоков. Запись можно начать в любое время или задать по расписанию. Сервис принимает входной поток, формирует последовательность hls-чанков и предоставляет интерфейс для последующей выгрузки в Filespot.

По факту API Gateway ходит во все микросервисы, фиксируя API для клиента. Изменения во «внутренних» сервисах, скрытых за API Gateway, не приводят к изменениям текущих внешних интерфейсов, предоставляемых клиентам, что значительно увеличивает скорость и гибкость разработки.

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

  • Атомарный сервис с автономными базами данных.
  • Минимизированное взаимодействие между сервисами.
  • Уменьшение потенциальных точек сбоя.
  • Упрощенное управление метаданными и объектами, включая загрузку, удаление и хранение файлов.
  • Специально разработанный API для беспрепятственного доступа к возможностям нашего хранилища.

Какую роль в изменении архитектуры сыграли Rust и Go?

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

Поэтому для создания хранилища данных я остановился на Rust. За счет низкоуровневого управления и высокой производительности Rust идеально подошел для разработки Storage. Система получилась устойчивой и удобной в обслуживании.

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

  1. Java,
  2. Golang,
  3. Python,
  4. Ruby,
  5. Rust.

Основную часть сервисов мы пишем на Go, а самые критичные к производительности (хранилище, парсинг access логов и подобное) на Rust.

Golang мы выбрали потому, что он быстро осваивается и является компилируемым (нам не надо думать о ресурсах). Язык поддерживает разработку параллельных сервисов, которые потом можно будет легко связать друг с другом, и у него даже есть свой Garbage Collector.

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

Выводы

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

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

Реклама ООО «ПК», ИНН: 7734690343