Web-сервис с простым сценарием и примерами использования инструментов, подходов к проектированию.
Основная функция сервиса - принимать из различных источников обьект с полями email/text, заполнять по нему письмо и по планировщику отправлять на smtp сервер. Сервис имеет 2 клиентские операции - создание и получение письма. Отправка письма на smtp сервер проходит асинхронно, по планировщику.
Импорт проекта в IntellijIDEA не требует настроек локальной среды,
проект может быть импортирован в IDE с помощью меню File->New->Project from existing sources->Gradle
.
- Используемые инструменты
- Техническое наполнение
- Развертка
- Использование
- Использование развёрнутой системы
- Публикация
Сервис построен на фреймворках, поддерживающих Reactive Streams спецификацию:
Для отправки email-сообщений используется фреймворк Spring Mail. Для работы с ним в неблокирующей среде используется пул Dispatchers.IO. В перспективе этот пул можно будет заменить на виртуальные потоки из Project Loom.
Полный список используемых библиотек можно найти в файле libs.versions.toml
Сервис имеет следующие технические возможности:
-
API представлен в двух типах: rsocket и http.
-
Создание письма через Kafka и отправка сообщений при изменении статуса.
-
Basic авторизация для rsocket/http с использованием Spring Security.
-
Используется бинарный формат данных Hessian для RSocket, с возможностью замены на CBOR.
-
Настроен мониторинг: метрики, логи, трейсы; метрики доступны по http.
-
Настроено jmx-подключение внутри docker-контейнера.
-
Работа с Postgres и миграции с помощью Flyway.
-
Использование Redis для хранения сообщений.
-
Распределенный планировщик с горизонтальным масштабированием с помощью ShedLock
-
Планировщик LoadScheduler для имитации работы с сервисом.
-
Описание http-спецификаций с помощью openapi.
-
При наличии гейтвея и достаточного количества партиций в kafka-очередях сервис поддерживает горизонтальное масштабирование и может использоваться в рамках kubernetes-кластера.
Кроме того, есть несколько особенностей github-репозитория:
- Автоматическое обновление версии сервиса в gradle.properties при релизе.
- Автоматические проверки качества: синтаксический анализ, тесты, статический анализ с Sonar.
- Настроена автоматическая сборка и выкладка docker-образа по созданию нового релиза в github. Результаты тестов и анализа кода доступны в Sonarcloud, docker-образ доступен в Docker registry
Наиболее удобно развернуть сервис и все стоонние системы используя Docker.
docker-compose up -d
Compose файл включает в себя следующие инструменты (с открытыми портами):
- Postgres - 7000
- PGAdmin - 4002
- Zookeeper - 2181
- Kafka - 29092
- Kafka-UI - 9001
- Schema Registry (будет использоваться в будущем) - 6005
- OtelCollector - 4317/4318/4319
- DataPrepper
- Opensearch
- Opensearch dashboards - 5601
- Clickhouse - 8123/9000
- DataLens - 8855
- KeyDB - 6379
- Prometheus - 9090 (пока opensearch не может принимать метрики в otlp формате)
- MailSlurper - 2500/8085/8083
- Mock server - 5001
- Сервис - localhost:8080, localhost:9091, localhost:7001, localhost:9010
Важно! Запуск потребует скачивания недостающих образов для запуска всех контейнеров и около 8 ГБ оперативной памяти в процессе работы развёртки.
Сервис может разворачиваться и локально, с использованием собранного исходного кода вместо docker-образа.
Для этого необходимо изначально провести развертку с использованием Docker compose файла,
после этого удалить контейнер с сервисом (service), собрать проект и запустить его либо через IDE,
либо внеся изменения в docker compose файл - раскомментировать строки build/context контейнера service
и убрать настройку image (предварительно собрать проект, получить jar).
Для запуска через IDE (например для проведения debug-а) необходимо прописать
системную переменную contour.database.port=7000
Доступные инструменты окружения:
- Kafka UI - позволяет также отправить ручные сообщения в очереди
- Openapi UI с описанием http-API сервиса - авторизация user/password
- PGAdmin - мастер-пароль 123, пароль для подключения к базе test
- Redis - Используется программа AnotherRedisDesktopManager. Подключение localhost:6379, пароль 123
- Smtp сервер
- Actuator API сервиса
- JMX подключение - Используется VisualVM. Локальное jmx соединение, адрес localhost:9010
- Opensearch logs
- Opensearch metrics - необходимо добавить prometheus, в dev tools выполнить следующий запрос
POST _plugins/_query/_datasources { "name" : "monitoring-prometheus", "connector": "prometheus", "properties" : { "prometheus.uri" : "http://monitoring-prometheus.monitoring:9090" } }
- Opensearch traces - необходимо создать index pattern traces-*
- DataLens - необходимо настроить подключение и создать дашборд по таблице queue.
Liveness
и readiness
API доступны по actuator/health/liveness
и actuator/health/readiness
путям.
Также для ручного вызова доступны API сервиса по адресам localhost:7001
(rsocket, websocket соединение), localhost:8080
(http).
Для работы с rsocket рекомендуется использовать Postman, для работы с http - Opanapi ui.
Важно! - rsocket API использует формат данных Hessian, поэтому постман в ответе на websocket-сообщение отобразит
только сырые байты
Когда проект собирается с использованием build
задачи gradle detekt и ktlint проверки проходят автоматически.
Detekt xml отчет формируется по путям ./build/app/reports/detekt
, ./build/api/reports/detekt
.
Также есть возможность запускать проверки вручную командой
.\gradlew detekt
Тестирование и измерение покрытия также проходят автоматически при вызове команды build
.
Покрытие измеряется инструментом kover, который в свою очередь использует движок JaCoCo.
Отчеты по покрытию (xml для sonar-инструментов и html для локальной разработки)
формируются по путям ./build/app/reports/kover/report.xml
, ./build/app/reports/kover/html/index.html
.
Также есть возможность вызвать тестирование и измерение покрытия вручную, вызвав команду
.\gradlew test koverPrintCoverage
Процент покрытия также можно смотреть и в самой IDE.
Для этого достаточно правой кнопкой мыши кликнуть на папку test и запустить задачу Run with Coverage.
Важно! Тесты не пройдут, если одновременно в докере развернут compose!
Прохождение Quality Gate реализовано с использованием gradle плагина sonarqube. Вызвать прохождение можно командами:
.\gradlew build
.\gradlew sonar -D"sonar.host.url"="<SONAR_HOST>" -D"sonar.token"="YOUR_TOKEN" -D"sonar.projectKey"="KEY" -D"sonar.organization"="ORG"
При вызове sonar с помощью gradle задачи сгенерированный detekt отчет и kover отчет будут добавлен к анализу.
Для тестирования будет полезна возможность локальной публикации пакетов в mavenLocal.
Для этого используется команда publishToMavenLocal.
.\gradlew publishToMavenLocal
В результате выполнения команды в .m2 папке пользователя появится артефакт mail-service-api, который будет содержать все
необходимые dto-классы, proto-файлы и другие нужные для взаимодействия с сервисом интерфейсы.