Меня зовут Кирилл, я работаю в компании Slotegrator и возглавляю отдел QA. Наша команда занимается разработкой платформ для онлайн-казино. У этого продукта очень разнообразный функционал, который включает в себя следующие пункты:
- Модуль регистрации и авторизации;
- Пополнение баланса и отслеживание статуса;
- Подтверждение пользователей;
- Бонусный модуль и т. д.
В этой статье речь пойдет о том, как нам удалось преодолеть трудности благодаря переходу на микросервисную архитектуру и как происходит процесс ее тестирования.
Как все начиналось?
В начале моей карьеры в Slotegrator, наша команда из 30-ти человек работала с 5-6 клиентами. И этого было достаточно, чтобы создавать платформу на PHP-монолите. То есть, она была построена как единое целое, где вся логическая обработка запросов помещалась внутрь одного процесса.
Но, со временем, наша компания значительно расширила свою клиентскую базу и разрабатывать платформу на монолите PHP стало не удобно, поскольку пожелания клиентов стали разнообразными и каждый хочет создать свою уникальную платформу.
У монолита модульная структура, которая включает в себя различные модули. Между этими модулями очень сильная связь, поэтому любое изменение одного из них отражается на функционировании всего приложения. При любом обновлении необходимо было выполнить множество команд. И самым большим недостатком в этом являлось то, что мы не могли выполнить обновления быстро.
Архитектура нашего продукта включает в себя следующие пункты:
- интерфейс пользователя;
- серверная часть, которая отвечает за бизнес-логику приложения;
- доступ к данным;
- база данных.
В монолитных приложениях очень ограниченная гибкость, т. к. в одном монолитном блоке объединены все модули и при разворачивании код находится на одном сервере. Таким образом, каждое небольшое обновление или изменение требует полного повторного развертывания новой версии всего приложения.
Работая с монолитом, у нас возникали сложности с масштабированием части приложения, поэтому мы были вынуждены делать это для всего приложения.
Например, запрос касательно игрового функционала происходит значительно чаще, нежели изменение контактных данных или просмотр новостей. В данной ситуации, необходимо было бы уделить этой функции больше внимания, но работая в монолите это просто невозможно. Чтобы обновить новую версию приложения, нужна большая команда, которая будет полностью соответствовать выбранной архитектуре. Однако, такой командой будет очень трудно управлять. В эту команду должны входить специалисты, которые проектируют пользовательский интерфейс, отдельные специалисты по бизнес-логике, базе данных и так далее. Тем не менее все эти команды должны полностью разбираться и уметь работать со всеми бизнес-функциями.
Почему микросервисы?
После того как наша команда столкнулась с рядом проблем, мы решили перейти на микросервисную архитектуру.
Миксервисная архитектура отличается от монолитной тем, что приложение создается как небольшие и независимые компоненты, которые можно развертывать, разрабатывать и поддерживать автономно друг от друга. Безусловно, здесь также есть свои трудности и подводные камни.
Увеличение количества небольших независимых сервисных единиц приводит к возрастанию операционной сложности. Поскольку невозможно обрабатывать десятки услуг без автоматизации их тестирования и развертывания, увеличивается роль непрерывной интеграции и доставки. Из-за технологического разнообразия сервисов возникают повышенные требования к мониторингу.
Однако, нам удалось преодолеть все эти трудности. Мы приобрели огромное количество новых знаний и навыков, а также овладели новыми инструментами.
И благодаря правильной организации работы у нас получилось обеспечить полноценное сотрудничество программистов, тестировщиков, разработчиков и других участников процесса. Это значительно ускорило процесс разработки платформы.
Тестирование микросервисов
Процесс тестирование микросервисной архитектуры значительно отличается от обычного. Микросервисная архитектура — это совокупность небольших сервисов, где каждый из них обслуживает одну бизнес-задачу. В целом эти небольшие сервисы являются готовым приложением и решают основную задачу.
Эти сервисы находятся на разных серверах и написаны на различных языках программирования, таких как Java и.Net. Однако, это также является и недостатком, поскольку разработчики определенного микросервиса практически не знают, что делают остальные микросервисы. Таким образом, это делает процесс тестирования не из легких.
Тем не менее у нас есть возможность обновить отдельный микросервис быстро и протестировать его не затронув другие.
Типы тестирования:
- unit-тестирование;
- контрактное тестирование;
- интеграционное тестирование;
- end-to-end тестирование;
- нагрузочное тестирование;
- UI- или функциональное тестирование.
Теперь рассмотрим подробнее все виды тестирования.
Unit-тестирование
Unit-тестирование (модульное тестирование) — это вид тестирования ПО, позволяющий проверить корректность отдельных модулей или компонентов программного обеспечения. Цель: проверка того, что каждая единица программного кода работает корректно.
Unit-тестирование бывает двух видов:
- позитивное (проверить поведение методов в нормальных условиях);
- негативное (проверить устойчивость системы к нештатным ситуациям).
Когда мы подходим к этапу разработки функционала, девелоперы самостоятельно пишут Unit-тесты, так как каждый из разработчиков лучше знает и понимает работу своего кода, и может лучше выполнить эту задачу, чем тестировщики.
Мы покрыли 70% функционала unit-тестами, и поскольку используем CI/CD, то не можем развернуть приложение, пока они не пройдены.
Контрактное тестирование
У нас работают над микросервисами несколько команд:
- бэкенд;
- фронтенд;
- тестировщики.
Чтобы понимать какой ендпоинт и в каком формате отдаёт и принимает данные, мы договариваемся между собой. Для этого, используем контракт между командами, который называется Pact. Он содержит в себе все методы и возвраты всех сервисов.
Контрактное тестирование подразумевает отношение к микросервису, как к черному ящику. Оно нацелено на то, чтобы мы могли убедиться, что все работает так как надо. Если одна из схем работает не по пакту, это считается дефектом.
Наша команда работает с контрактным тестированием следующим образом: мы получаем ТЗ, которое согласованно со всеми стейкхолдерами. Согласно техническому заданию, мы оцениваем задачи и создаем схему работы.
Интеграционное тестирование
Во время интеграционного тестирования проверяется, насколько корректно разные микросервисы взаимодействуют друг с другом. Этот вид тестирования считается самым критичным тестом всей архитектуры. При положительном исходе тестирования мы можем быть уверены, что она спроектирована правильно, и все независимые микросервисы работают как единое целое в соответствии с ожиданиями.
End-to-end тестирование
E2E тестирует бизнес-логику подобно процессу тестирования в интеграционном, но уже не изолированно, а в масштабе всей системы.
В end-to-end тестировании проверяется, как взаимодействуют все сервисы c платформой:
- регистрация;
- авторизация;
- игровая деятельность;
- пополнение и снятие денежных средств.
То есть мы проверяем насколько соответствует все приложение запросам заказчика.
Нагрузочное тестирование
Процесс нагрузочного тестирования формально делится на 4 этапа:
- тестирование производительности (Performance Testing);
- тестирование стабильности или надежности;
- стресс-тестирование;
- объемное тестирование (Volume Testing).
Для тестирования, мы используем JMeter, а сами нагрузочные скрипты написаны на Groovy.
Также, мы используем около пяти виртуальных машин, развернутых на AWS и у нас есть 7 физических машин. Физические машины, мы используем если нам необходимо создать большую нагрузку от 15,000 RPS и более. Виртуальные машины такие показатели дать не могут, поскольку каждый запрос необходимо отправлять с подписью шифрования, вследствие чего процессор сильно нагружается. Поэтому, мы используем виртуальные машины только для фоновой или статической нагрузки — 2000 RPS.
Что касается статистики, мы её собираем в Grafana. После чего, мы анализируем все показатели, такие как нагрузка на CPU, GPU, сеть, диски и т. д.
UI- или функциональное тестирование
Это итоговый вид тестирования. Мы тестируем практически все то же самое, что и при end-to-end тестировании, но только с использованием UI. Мы проводим UI тестирование мануально и также делаем автотесты.
Вывод
У микросервисной архитектуры есть свои плюсы и минусы, поэтому она подойдет не всем. Все зависит от продукта, который вы разрабатываете. Для небольших приложений, которые редко обновляются, достаточно использовать монолит. Мы пришли к использованию микросервисной архитектуры, потому что у нас расширялся и функционал приложения. Несмотря на все трудности, для нашего проекта использовать микросервис — это преимущество. Теперь нам значительно легче внедрять что-то новое, развиваться и улучшаться.
Релоцировались? Теперь вы можете комментировать без верификации аккаунта.