Как добиться транзакционной целостности данных? | OTUS
🔥 Начинаем BLACK FRIDAY!
Максимальная скидка -25% на всё. Успейте начать обучение по самой выгодной цене.
Выбрать курс

Курсы

Программирование
iOS Developer. Basic
-25%
Python Developer. Professional
-25%
Разработчик на Spring Framework
-25%
Golang Developer. Professional
-25%
Python Developer. Basic
-25%
iOS Developer. Professional
-25%
Highload Architect
-25%
JavaScript Developer. Basic
-25%
Kotlin Backend Developer
-25%
JavaScript Developer. Professional
-25%
Android Developer. Basic
-25%
Unity Game Developer. Basic
-25%
Разработчик C#
-25%
Программист С Web-разработчик на Python Алгоритмы и структуры данных Framework Laravel PostgreSQL Reverse-Engineering. Professional CI/CD Vue.js разработчик VOIP инженер Программист 1С Flutter Mobile Developer Супер - интенсив по Kubernetes Symfony Framework Advanced Fullstack JavaScript developer Супер-интенсив "Azure для разработчиков"
Инфраструктура
Мониторинг и логирование: Zabbix, Prometheus, ELK
-25%
DevOps практики и инструменты
-25%
Архитектор сетей
-25%
Инфраструктурная платформа на основе Kubernetes
-25%
Супер-интенсив «ELK»
-16%
Супер-интенсив «IaC Ansible»
-16%
Супер-интенсив "SQL для анализа данных"
-16%
Базы данных Сетевой инженер AWS для разработчиков Cloud Solution Architecture Разработчик голосовых ассистентов и чат-ботов Внедрение и работа в DevSecOps Администратор Linux. Виртуализация и кластеризация Нереляционные базы данных Супер-практикум по использованию и настройке GIT IoT-разработчик Супер-интенсив «СУБД в высоконагруженных системах»
Специализации Курсы в разработке Подготовительные курсы
+7 499 938-92-02

Как добиться транзакционной целостности данных?

Когда осуществляется переход с монолитной архитектуры на микросервисную, команды, не имеющие опыта, зачастую начинают дробить свои сервисы по верхнеуровневым объектам доменной модели (к примеру, User/Client/Employee и т. п.). И это ошибка номер один. При более детальной проработке возникает понимание, что разбивать удобнее и лучше на более крупные блоки, которые агрегируют внутри себя несколько объектов доменной области. Такое решение позволит вам избежать лишних вызовов в сторонние сервисы.

Второй нюанс — поддержка транзакционной целостности данных. В том же монолите данная задача решается с помощью Application Server, где крутится war/ear, а внутри него контейнер, можно сказать, очерчивает границы транзакций. Но когда мы говорим о микросервисах, то здесь границы транзакций размазываются, в результате чего нам, кроме написания кода бизнес-логики, надо ещё и иметь возможность управлять целостностью данных, поддерживая их согласованность между различными частями системы. Это уже нетривиальная задача, однако рекомендации по решению таких архитектурных проблем вы можете найти в сети и на соответствующих технических форумах.

Мы же поговорим о конкретных технических сложностях, возникающих в процессе работы с микросервисами. Вообще, главная проблема при такой работе — микросервисы очень легко запустить локально (к примеру, с помощью spring.io и intellij idea в это сделаете всего за 5 минут). Но при попытке сделать это в Kubernetes-кластере (при небольшом опыте работы с ним) обыкновенный запуск контроллера, который печатает «Hello World» при обращении к определенному endpoint, способен занять у вас целых полдня. Здесь у монолитов ситуация проще: каждый разработчик имеет локальный Application Server, а процесс деплоя весьма прост — надо скопировать конечный артефакт war/ear в необходимое место в Application Server, сделав это вручную либо средствами IDE.

Нюансы отладки

Итак, когда у вас монолит, предполагается, что на машине разработчика есть Application Server, на который осуществляется деплой его war/ear. Всё, что надо, есть под рукой, поэтому всегда можно провести отладку. В случае с микросервисной архитектурой всё несколько сложнее, ведь сервис, как правило, — это вещь в себе. Обычно он имеет собственную схему базы данных, в которой лежат его данные, выполняет присущие лишь ему функции, а всё общение с иными сервисами организовано посредством синхронных HTTP-вызовов (к примеру, с помощью RestTemplate либо Feign; асинхронные — Kafka либо RabbitMQ). В результате, простая задача сохранения либо валидации какого-нибудь объекта, которая ранее реализовывалась в одном месте и внутри одного war/ear-файла, в случае с микросервисной архитектурой представляется в виде необходимости сходить в один либо n смежных сервисов. Всё это ведёт к тому, что прописывать бизнес-логику становится значительно труднее.

Какие могут быть тут варианты решения:

  1. Написать собственный код бизнес-логики. При этом все внешние вызовы мокаются (mock), то есть эмулируются внешние контракты и пишутся тесты, после чего в контур для проверки осуществляется деплой. Иногда интеграция работает сразу, но порой приходится переделывать код бизнес-логики, ведь за время реализации функциональности код в смежном сервисе мог быть обновлён, а сигнатуры API изменены.
  2. Выполнить отладку. Необходимо либо логировать всё, что можно, а потом вдумчиво читать логи после деплоя в Kubernetes (мы же помним, что полноценно и локально воспроизвести ситуацию невозможно, так как отсутствует интеграция с нужными сервисами). Либо надо подключаться в контур по remote debug. Станет лучше в том плане, что вы сможете посмотреть в runtime, что и как. Но существуют и минусы: — процесс не всегда бывает быстрым, вы можете запустить режим отладки и ожидать 2–5 минут, ведь по факту вы можете быть не в той сети, где находится Kubernetes-кластер, а накладные сетевые расходы никто не отменял; — не следует забывать ставить режим отладки отдельно для каждого потока (Per thread). В обратном случае, пока вы выполняете отладку, остальные могут смело идти курить.

Источник

Не пропустите новые полезные статьи!

Спасибо за подписку!

Мы отправили вам письмо для подтверждения вашего email.
С уважением, OTUS!

Автор
0 комментариев
Для комментирования необходимо авторизоваться
🎁 Максимальная скидка!
Черная пятница уже в OTUS! Скидка -25% на всё!