ОСОБЕННОСТИ КОММУНИКАЦИИ МИКРОСЕРВИСОВ ПРИ ИСПОЛЬЗОВАНИИ ШАБЛОНА САГА


Цитировать

Полный текст

Аннотация

Сегодняшние облачные решения очень часто строятся на основе микросервисной архитектуры. При таком подходе система реализуется в виде набора слабо связанных сервисов, которые не разделяют общего хранилища и обмениваются данными и командами по сети. Наряду с преимуществами такая структура системы привносит свои недостатки, в частности - усложнение алгоритмов обеспечения согласованности данных. Известным решением проблемы является архитектурный шаблона сага, который подразумевает обеспечение итоговой согласованности, однако не формализует требования к свойствам отказоустойчивости системы, что может привести к отсутствию согласованности при изменении данных. В работе разбираются архитектурные особенности обеспечения отказоустойчивости в сагах в разрезе протоколов взаимодействия сервисов. Для этого был проанализирован ряд научных работ, посвященных сагам, и определены наиболее распространенные способы коммуникации. Для сформированного ряда протоколов были определены потенциальные уязвимости и предложены решения для сохранения отказоустойчивости в системе. Были показаны способы модификации взаимодействия сервисов с использованием стандартных реализаций протоколов для изменения наличия свойства синхронности взаимодействия микросервисов. Показаны преимущества использования таких технологий, как DLQ и CQRS, для формирования отказоустойчивых саг.

Полный текст

Введение В микросервисной среде доступ к данным ограничен, поэтому только микросервис, реали- зующий логику определенной области приложе- ния, имеет доступ к хранилищам данных этой области. Работа с данными из других областей системы производится через заранее оговорен- ные сетевые контракты (API). Такая структура позволяет независимо развивать участки прило- жения, изменяя способы хранения данных без на- рушения сетевых контрактов, и открывает доступ к горизонтальному масштабированию системы для работы с высокой нагрузкой [1]. Однако микросервисная архитектура услож- няет процессы, которые обеспечивают согласо- ванность данных сразу на нескольких участках системы. До прихода микросервисов данные из разных областей сохранялись в одной БД, и изменения в этих областях можно было провести атомарно и изолированно с помощью транзакций базы дан- ных. При микросервисной архитектуре данные распределены сразу по нескольким БД, что не по- зволяет произвести простую транзакцию. Известны способы организации распределен- ных транзакций сразу в нескольких БД, такие как Two-phase commit (2PC) [2]. Но такие подходы не получили широкого распространения при ис- пользовании микросервисов в системе ввиду на- личия критических недостатков при существен- ных нагрузках на систему [3]. Альтернативой распределенным транзакциям является организация изменений в ключе итого- вой согласованности данных. При таком подхо- де данные изменяются без изоляции и поэтапно. То есть согласованность обеспечивается не сразу на всех участках системы, а постепенно. Эта идея была концептуализирована для ми- кросервисных систем в архитектурном шаблоне с названием «сага». Каждая сага - это набор локальных тран- закций и компенсаций. Локальные транзакции в саге - это цепочка запросов на изменение данных в микросервисах. В случае возникновения ошиб- ки применения локальной транзакции в одном из сервисов система должна применить компен- сации во всех сервисах, которые уже выполнили локальные транзакции. Применение компенса- ций призвано восстановить исходное состояние системы в случае ошибок. В распределенном программном решении сага может быть реализована одним из двух спо- собов [4]. Хореография саг - при хореографии сага реализуется в каждом сервисе-участнике саги. Выполнив свою локальную транзакцию, сервис отправляет запрос следующему по цепочке сер- вису. Когда все следующие микросервисы вы- полнили свою часть изменений, они отправляют подтверждение об успешности выполнения пре- дыдущему сервису. Полученное подтверждение позволяет сервису скомпенсировать изменения, если в цепочке вызовов произошла ошибка. На рисунке 1 продемонстрирована цепочка вы- полнения локальных транзакций и компенсаций при реализации саги в хореографической форме. Сервисы 1 и 2 успешно выполняют локальные транзакции и передают управление сервису 3. При выполнении локальной транзакции на сер- висе 3 происходит ошибка, из-за чего подтверж- дение с информаций об ошибке возвращается на предыдущие сервисы. Получив подтверждение, сервисы 2 и 1 применяют компенсации для воз- вращения текущего состояния к моменту до про- ведения локальных транзакций. Оркестрация саг - при оркестрации саг в системе реализуется отдельный сервис («коор- динатор»), ответственный за управление ходом саг. Это позволяет произвести инкапсуляцию ло- гики, связывающей различные области приложе- ния, предотвращая изменение контролируемых Рисунок 1. Обработка ошибки в локальной транзакции при хореографии саг Рисунок 2. Обработка ошибки в локальной транзакции при оркестрации саг микросервисов в случае изменения связывающей логики. На рисунке 2 представлена аналогичная си- туация с ошибкой при проведении локальной транзакции саги в сервисе 3. Отличие заключает- ся в том, что только координатор саг отправляет запросы на выполнение локальных транзакций, агрегирует подтверждения и производит запросы на выполнение компенсаций для сервисов, если это необходимо. Важным аспектом выполнения саг является реакция системы на отказ одного из компонентов саги. Учитывая природу итоговой согласован- ности данных, когда модификация происходит не атомарно, отказ одного из участков системы может привести к отсутствию согласованности в системе. Отказоустойчивая структура саги должна по- зволить предотвратить ситуации такого рода в любом из подходов реализации саг. Поэтому в данном исследовании мы рассмотрели различ- ные способы по обеспечению отказоустойчиво- сти системы на основе саг, делая упор на канал передачи данных в системе. Проведенные исследования Для рассмотрения аспектов отказоустойчи- вости в каналах коммуникации саг нами был проанализирован ряд последних научных работ, посвященных использованию саг в микросервис- ной архитектуре. В [5] проводится разбор нескольких про- граммных пакетов с разным способом организа- ции коммуникации между сервисами. Axon Service - этот программный пакет по- строен для работы с CQRS (Command and Query Responsibility Segregation) архитектурой. Axon Service использует систему событий из Spring Boot библиотеки для того, чтобы обеспе- чить коммуникацию в пределах одного сервиса. Но пользователь программного пакета может расширить его своим способом коммуникации. Это значит, что структура саги и способ органи- зации локальных транзакций и компенсаций пол- ностью обеспечиваются разработчиком, который внедряет пакет в систему. Eventuate Service - это программный пакет также создан для обеспечения принципов CQRS. Протоколы для организации локальных тран- закций в нем ограничены использование REST. Описание локальных транзакций и компенсаций также является ответственностью разработчика системы. Eventuate Tram Service - данный программ- ный пакет поддерживает автоматическую отправ- ку событий при выполнении изменений в БД. По умолчанию управление сообщениями реализова- но на основе Apache Kafka. Отправленное собы- тие приводит к активации следующей локальной транзакции. Eventuate Tram Service выполняет локальные транзакции одну за другой и произво- дит компенсацию в случае возникновения ошиб- ки в одной из них. LRA Service - в этом программном пакете организация взаимодействия с микросервисами осуществляется с помощью протокола HTTP. Структура саги определяется специалистом, адаптирующим пакет под систему. В [6] авторы предложили свой программный пакет для организации саг. В их программной ре- ализации используются 2 протокола для обеспе- чения коммуникации. HTTP: для организации RESTful коммуни- кации с полезной нагрузкой в формате JSON для коммуникации сервисов; CArtAgO: основанный на событиях способ коммуникации между сервисом и его управля- ющим агентом. Агент в SagaMAS - это сервис, который должен быть индивидуально развернут для каждого микросервиса в саге. Именно агенты обеспечивают выполнение саги. Авторы [7] описывают обновление архитекту- ры одного из распределенных приложений. В описанном проекте они предложили ис- пользовать брокер сообщений (RabbitMQ) для организации локальных транзакций. Однако, как показано в статье, руководство проекта приняло решение не реализовывать предложенный протокол взаимодействия серви- сов и обойтись коммуникацией в саге через ре- ляционную базу данных, которая уже использо- валась в системе. В исследовании [8] авторы ссылаются на книгу [9]. В ней предлагается использование брокеров сообщения для формирования взаимо- действия сервисов в саге. Основной указанной причиной использования именно брокеров со- общений является возможность предотвратить утерю сообщений в случае, когда получатель со- общения (сервис или координатор) временно не может его обработать. В [10] также предложено использование про- токолов, основанных на сообщениях. В [11] представлен анализ Eventuate Tram Service (который был упомянут ранее) в сравне- нии с Netflix Conductor. Последний программный пакет предлагает ис- пользовать REST как способ организации локаль- ных транзакций в стандартной конфигурации. Проведенная оценка публикаций показала, что авторы научных статей обращаются именно к уже популярным протоколам коммуникации в микросервисных средах. Популярность подходов в организации микросервисного взаимодействия среди разработчиков систем можно оценить по результатам опроса (рисунок 3), который провела компания JetBrains в 2021 году [12]. По результатам проведенного нами анализа становится заметно, насколько ответственность за формирование эффективной структуры саги смещена в сторону разработчика системы, что Рисунок 3. Результат исследования компании JetBrains увеличивает шанс на появление ошибок, которые могут привести к несогласованности данных. Для более детального рассмотрения этих оши- бок и определения способов их предотвращения мы предлагаем разобрать два аспекта организа- ции взаимодействия саг в микросервисной среде: свойства протоколов взаимодействия сервисов и архитектурный компонент коммуникации в сагах. Подтверждение локальных транзакций Для формирования эффективного взаимодей- ствия сервисов в саге важно определить свойства ключевого элемента - подтверждений локальных транзакций и компенсаций. Подтверждения в сагах нужны для (1) воз- можности определить завершение выполнения саги и для (2) передачи вызывающей системе ин- формации о наличии или отсутствии ошибки при выполнении команды, чтобы вызывающая сто- рона могла среагировать на ошибку, например, компенсацией, если подтверждение относилось к команде. Подтверждения также позволяют предотвра- тить компенсационные коллизии. Такого рода коллизии происходят из-за возможности парал- лельной обработки запросов на одном сервисе или из-за наличия нескольких экземпляров одно- го сервиса в системе. Поэтому без системы подтверждений отправ- ка компенсации после отправки запроса на проведение локальной транзакции не будет гаранти- ровать установленный порядок выполнения. Как показано на рисунке 4, запрос на проведе- ние компенсации может быть применен раньше запроса на проведение локальной транзакции, так как локальная транзакция выполняется па- раллельно и ее применение может занять больше времени. Наряду с уже указанными факторами воз- можность сворачивания реплик микросерви- сов [13] увеличивает вероятность невыполнения локальных транзакций и компенсаций. Ожида- ние подтверждений от сервисов устраняет и эту проблему для протоколов, которые не поддержи- вают автоматическое повторение извлечения дан- ных [14]. Используемые протоколы В данной работе рассматриваемые протоколы коммуникации сервисов разделены на клиент- серверные и протоколы на основе очередей со- общений, как показано в таблице. Клиент-серверные протоколы рассмотрены в контексте синхронного выполнения команд и компенсаций, т. е. выполнение запроса про- исходит именно в момент коммуникационной сессии. А очереди сообщений ассоциированы с асинхронным выполнением запроса на стороне микросервиса. Рисунок 4. Обработка компенсации до обработки команды, несмотря на более раннее получение команды Таблица. Рассматриваемые протоколы Тип Название Историч- ность Повтор при ошибках Клиент- серверные HTTP - - CoAP - - Очереди сообщений Kafka Сохранение в файл DLQ RabbitMQ - DLQ ActiveMQ - DLQ Redis - - Такое отношение типа протокола к свойству синхронности выполнения не является строгим и поддается корректировке. Его можно изменить при внедрении дополнительной сложности в ал- горитм взаимодействия систем в саге. Синхронное выполнение локальных транзакций Стандартное поведение систем с использова- нием клиент-серверных протоколов, таких как HTTP, предполагает блокировку клиентской ча- сти после отправки запроса до момента получе- ния ответа. Известны программные реализации клиент-серверных протоколов, которые позволя- ют производить другие операции до получения ответа, что может позволить справляться с высокой нагрузкой [15]. Однако получение ответа в клиент- серверных протоколах - это ключевая часть кон- тракта между участниками взаимодействия. Получение ответа от системы может быть адаптировано для роли подтверждения выполне- ния локальной транзакции. Но при таком исполь- зовании ответа на передний план выходит про- блема отказа одной из сторон взаимодействия. Отказ возможен на стороне координатора после отправки запроса или на стороне сервиса-участ- ника саги, после того как тот получил запрос на выполнение локальной транзакции/компенсации. В таком случае серверный ответ уже не удастся извлечь даже после восстановления отказавшего участка. Реализация свойств идемпотентности позво- ляет координатору повторить запрос после вос- становления и добиться подтверждения без вне- сения излишнего дублирования изменений. Как показано на рисунке 5, сервис может отка- зать уже после получения команды и выполнения изменений, но перед отправкой подтверждения. В случае если реализация выполнения команды представлена в идемпотентном варианте, то по- вторное получение команды не приводит к по- втору изменений данных. Оно приводить лишь к формированию и отправке подтверждения вы- полнения команды. Альтернативой можно считать сохранение запроса в сервисе, что позволит обработать его асинхронно. Этот подход сходен с архитектурны- ми решениями на основе CQRS, что позволяет вернуться к обработке запроса в случае ошибки на стороне сервиса (рисунок 6). При таком подхо- де ответ клиент-серверного протокола не играет существенной роли в коммуникации [16]. Асинхронное выполнение локальных транзакций Известными протоколами для организации асинхронного взаимодействия на основе очере- дей сообщений являются MQTT, AMQP и раз- личные реализации, такие как: Kafka, Rabbit MQ, Apache ActiveMQ, Redis. При их использовании в сагах сообщения мо- гут уведомлять как о команде и компенсации, так Рисунок 5. Повтор команды при ошибке на стороне сервиса Рисунок 6. Асинхронное применение клиент-серверного протокола и о подтверждении проведения команды или ком- пенсации. На фоне клиент-серверных протоколов оче- реди сообщения выгодно отличаются возможно- стью повторного извлечения сообщения после восстановления системы в случае отказа. Это позволяет не повторять запрос на стороне, запраши- вающей выполнение команды. Такая возможность предоставляется некоторыми очередями на основе технологий, таких как Dead Letter Queue (DLQ). На рисунке 7 представлен пример повторной обработки сообщений с помощью DLQ в случае Рисунок 7. Повтор команды при применении брокера сообщений с DLQ отказа на стороне сервиса. Здесь брокер сообще- ний позволяет повторно извлечь сообщение, для которого не было сформировано подтверждение. При этом координатор остается изолирован от процесса повторной обработки сообщения. Некоторые очереди сообщений также предо- ставляют возможность извлечь историчные дан- ные [16], что позволит восстановить причину возникновения ошибок в таких ситуациях, как конфликт при применении компенсации. CQRS-архитектура часто совмещается с со- бытийно ориентированной архитектурой [15]. Восстановление прогресса выполнения саги при такой структуре системы возможно и без допол- нительных функций, предоставляемых очередя- ми сообщений. Дальнейшее исследование Построение архитектуры системы с учетом возможных ошибок в каналах коммуникации раз- личных участков системы позволит повысить показатели отказоустойчивости при выполнении саг, однако не будет гарантировать согласован- ность данных. Отсутствие изоляции внесенных изменений при выполнении саги подразумевает возможность параллельного появления несовме- стимых модификаций, что приведет к невозможности произвести компенсацию. В таком случае данные будут оставлены в несогласованном со- стоянии до момента ручной обработки ошибки. По этой причине изучение свойств описанных коллизий при выполнении компенсаций позволит продвинуться в разработке методов формирова- ния архитектуры саг с обеспечением максималь- ных показателей согласованности данных. Заключение В работе был представлен разбор наиболее используемых способов коммуникации микро- сервисов в контексте разработки архитектуры си- стем с использованием саг. Показаны структурная разница протоколов и влияние этой разницы на отказоустойчивость си- стемы. Для этого способы коммуникации были разделены на синхронные и асинхронные с ука- занием преимуществ и недостатков для форми- рования отказоустойчивой архитектуры системы. Были представлены способы адаптации раз- ных типов протоколов коммуникации в сагах для соответствия требованиям отказоустойчивости в системах. Также были продемонстрированы ме- тоды изменения структуры взаимодействия при использовании клиент-серверных протоколов и очередей сообщения для применения протоколов в асинхронном и синхронном варианте соответ- ственно. Работа призвана помочь исследователям и инженерам в области распределенных облачных вычислительных решений на основе микросер- висов.
×

Об авторах

К. В Малюга

Национальный исследовательский университет ИТМО

Email: konstantin.malyuga@gmail.com
Санкт-Петербург, РФ

И. А Перл

Национальный исследовательский университет ИТМО

Email: ivan.perl@itmo.ru
Санкт-Петербург, РФ

Список литературы

  1. Brown K., Woolf B. Implementation patterns for microservices architecture // Proceedings of the 23rd Conference on Pattern Languages of Programs (PLoP ’16). 2016. P. 7-1-35
  2. Two-phase commit optimizations and tradeoffs in the commercial environment / G. Samaras [et al.] // Proceedings of IEEE 9th International Conference on Data Engineering. 1993. P. 520-529
  3. Towards dependable agent systems /j. Nimis [et al.] // Multiagent Engineering. 2006
  4. Rudrabhatla C.Comparison of event choreography and orchestration techniques in microservice architecture // International Journal of Advanced Computer Science and Applications. 2018. P. 9
  5. Štefanko M., Chaloupka O., Rossi B. The saga pattern in a reactive microservices environment // 14th International Conference on Software Technologies. 2019. P. 483-490
  6. SagaMAS: ASoftware framework for distributed transactions in the microservice architecture / X. Limón [et al.] // 6th International Conference in Software Engineering Research and Innovation (CONISOFT). 2018. P. 50-58
  7. Assessing migration of a 20-year-old system to a micro-service platform using ATAM / P. Cruz Navea [et al.] // IEEE International Conference on Software Architecture Companion (ICSA-C). 2019. P. 174-181
  8. Microservice patterns for the life cycle of industrial edge software / F. Li [et al.] // EuroPLoP ’18: Proceedings of the 23rd european conference on pattern languages of programs. 2018. P. 1-11
  9. Richardson C. Microservices patterns. Shelter Island: Manning, 2018. 520 p
  10. Li Z., Liang P., Avgeriou P. Architectural technical debt identification based on architecture decisions and change scenarios // Proceedings 12th Working IEEE/IFIP Conference on Software Architecture, WICSA. 2015. 63 p
  11. Dürr K., Lichtenthäler R., Wirtz G. An evaluation of saga pattern implementation technologies // CEUR Workshop Proceedings. 2021. 74 p
  12. Микросервисы // JetBrains. URL: https://www.jetbrains.com/ru-ru/lp/devecosystem-2021/microservices (дата обращения: 19.10.2021)
  13. Deploying microservice based applications with Kubernetes: Experiments and lessons learned / V. Leila [et al.] // IEEE 11th International Conference on Cloud Computing (CLOUD). 2018. P. 970-973
  14. Fault tolerant central saga orchestrator in RESTful architecture / K. Malyuga [et al.] // Proceedings of the XXth Conference of Open Innovations Association FRUCT. 26. 2020. P. 278-283
  15. Knoche H. Improving batch performance when migrating to microservices with chunking and coroutines // Softwaretechnik-Trends. 2019. No. 39 (4). P. 20-22
  16. An empirical characterization of event sourced systems and their schema evolution - Lessons from industry / M. Overeem [et al.] // Journal of Systems and Software. 2021. 178 p

Дополнительные файлы

Доп. файлы
Действие
1. JATS XML

© Малюга К.В., Перл И.А., 2021

Creative Commons License
Эта статья доступна по лицензии Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.