разработчик программного обеспечения, РФ, г. Самара
АНТИПАТТЕРНЫ ПОСТРОЕНИЯ МИКРОСЕРВИСНЫХ ПРИЛОЖЕНИЙ В ВЫСОКОНАГРУЖЕННЫХ ПРОЕКТАХ
АННОТАЦИЯ
Микросервисная архитектура стремительно распространяется благодаря своей способности обеспечивать гибкость, масштабируемость и быстрое внедрение изменений. Однако, как и в любой технологии, существуют свои сложности и недостатки, которые могут принизить все преимущества микросервисов.
Микросервисная архитектура – это методика разработки программного обеспечения, где приложение делится на небольшие, слабо связанные и автономные сервисы, каждый из которых выполняет свою функцию. Эти сервисы взаимодействуют друг с другом через сетевые запросы, передавая необходимые данные по API. Такой подход обеспечивает высокую гибкость, легкость масштабирования и возможность вносить изменения в отдельные компоненты, не затрагивая всю систему.
Популярность микросервисов в разработке обусловлена их множеством преимуществ. Прежде всего, возможность горизонтального масштабирования позволяет легко адаптировать систему под увеличивающуюся нагрузку, добавляя новые экземпляры микросервисов. В дополнение, отдельные микросервисы могут быть написаны на разных языках программирования, что дает разработчикам большую свободу в выборе технологий. Кроме того, внесение изменений в микросервисы упрощено, так как это ограничивается только изменением соответствующего сервиса, не требуя модификации всего приложения.
В связи с чем при написании работы автором была выделена цель в исследовании антипатернов построения микросервисных приложений в высконагруженных проектах.
При написании работы в качестве методологической базы выступают научные статьи, результаты опытов, специализированная литература, выступления на конференциях. Благодаря чему стало возможным всестороннее и полностью рассмотреть такую важную тему как: антипатерны построения микросервисных приложений в высоконагруженных проектах.
ABSTRACT
Microservice architecture is rapidly spreading due to its ability to provide flexibility, scalability and rapid implementation of changes. However, as with any technology, there are difficulties and disadvantages that can belittle all the advantages of microservices.
Microservice architecture is a software development technique where an application is divided into small, loosely coupled and autonomous services, each of which performs its own function. These services interact with each other through network requests, transmitting the necessary data via the API. This approach provides high flexibility, ease of scaling and the ability to make changes to individual components without affecting the entire system.
The popularity of microservices in development is due to their many advantages. First of all, the possibility of horizontal scaling makes it easy to adapt the system to the increasing load by adding new instances of microservices. In addition, individual microservices can be written in different programming languages, which gives developers more freedom in choosing technologies. In addition, making changes to microservices is simplified, since it is limited only to changing the corresponding service, without requiring modification of the entire application.
In this connection, when writing the work, the author singled out the goal in the study of anti-patterns of building microservice applications in overloaded projects.
When writing a paper, scientific articles, experimental results, specialized literature, and conference presentations serve as a methodological basis. Thanks to this, it became possible to comprehensively and fully consider such an important topic as: the antipatterns of building microservice applications in high-load projects.
Ключевые слова: микросервисы, микросервисные приложения, проекты, антпатерны, антипатерны построения микросервисных приложений.
Keywords: microservices, microservice applications, projects, antipatterns, antipatterns of building microservice applications.
Введение
Антипаттерны – это повторяющиеся решения проблем, которые могут казаться интуитивно верными, но на практике приводят к негативным последствиям. Их применение при проектировании систем всегда рассматривается как неудачная практика. Ниже будут представлены антипаттерны в архитектуре микросервисов:
- Распределенные монолитные системы: Этот антипаттерн часто возникает, когда большие монолитные приложения пытаются разделить на множество маленьких монолитов, под видом микросервисов. Однако взаимодействие этих маленьких монолитов друг с другом может быть сложным и привести к разрывам в работе системы.
- Хаос сплоченности и сцепление: В микросервисной архитектуре важно, чтобы каждый микросервис занимался только своими делами и не заботился о компонентах других процессов. Однако, при постоянном добавлении несвязанных компонентов или функциональностей в один микросервис, возникает хаос в сплоченности и сцеплении компонентов.
- Искажение зависимостей: Этот антипаттерн возникает, когда микросервисы должны быть развернуты в определенном порядке, чтобы поддерживать связь между ними. Это может быть вызвано неправильным разделением обязанностей.
- Общие схемы и хранилища данных: Если несколько микросервисов подключены к одной базе данных и один из них требует изменения схемы, это приводит к сложностям в адаптации других микросервисов к этим изменениям.
- Избыточность действий: Избыточные действия возникают, когда некоторые функциональности повторяются в каждом микросервисе. Централизованная логика через API-шлюз может управлять аутентификацией событий, что делает систему более удобной и эффективной [1].
Антипаттерны в микросервисной архитектуре
Исследование антипаттернов приобретает особую важность для разработчиков и архитекторов по нескольким причинам.
Во-первых, они помогают избежать распространенных ошибок, повышая качество проектирования.
Во-вторых, антипаттерны предупреждают о нежелательных последствиях и предоставляют рекомендации по корректному построению системы.
Наконец, они развивают аналитическое мышление и способность видеть "большую картину".
- Антипаттерн "Избыточная мелкость микросервисов"
Проблема заключается в чрезмерной декомпозиции, которая приводит к созданию большого количества крайне мелких микросервисов. Хотя микросервисы предназначены для обеспечения гибкости и изоляции компонентов, излишнее дробление функциональности на слишком мелкие сервисы может вызвать серьезные проблемы. Несмотря на то, что больше микросервисов может показаться лучшим решением, на практике это может привести к сложностям в управлении и большим накладным расходам на коммуникацию.
Слишком мелкие микросервисы означают, что каждый сервис становится отдельным приложением с собственным кодом, базой данных, зависимостями и API. Это увеличивает сложность управления, поскольку команде разработчиков приходится поддерживать множество кодовых баз, следить за мониторингом и обновлениями. Постоянное взаимодействие между мелкими микросервисами приводит к большому количеству сетевых запросов, что может стать узким местом системы, вызывая задержки и увеличивая нагрузку на сеть.
Для того, чтобы избежать данную проблему необходимо найти баланс между гранулярностью микросервисов и уровнем сложности управления ими. Важно учитывать функциональную связность – какие компоненты логически должны взаимодействовать. Если функциональности часто взаимодействуют между собой, их можно объединить в один микросервис, снижая тем самым накладные расходы на коммуникацию [2]. Оптимальное количество микросервисов зависит от конкретных требований и контекста проекта. Стремитесь к разумной гранулярности, которая обеспечивает независимость и эффективное взаимодействие компонентов системы.
- Антипаттерн "Косметическая микросервисность"
Проблема этого антипаттерна заключается в сознательном игнорировании ключевых принципов микросервисной архитектуры в погоне за внешней красотой. Разработчики, стремясь выглядеть современно и следовать трендам, создают видимость микросервисной архитектуры, но при этом не придерживаются сути и основных принципов этого подхода. Вместо настоящей изоляции и независимости, микросервисы остаются тесно связанными и зависимыми друг от друга, что приводит к отсутствию реальной модульности, несмотря на видимую декомпозицию. Создание "косметических" микросервисов может привести к сложностям при масштабировании и внесении изменений. Вместо гибкости и независимости, система становится трудноуправляемым монолитом с избыточными связями и общими ресурсами. Этот подход не только делает систему менее гибкой, но и затрудняет внесение изменений, так как каждое изменение требует вмешательства в несколько связанных микросервисов одновременно.
Чтобы избежать "Косметической микросервисности", необходимо строго придерживаться ключевых принципов микросервисной архитектуры:
- Тщательное планирование граничных контекстов: Определите граничные контексты вашей системы и убедитесь, что микросервисы находятся внутри своих контекстов, избегая смешивания функциональности внутри них.
- Независимость и изоляция: Каждый микросервис должен иметь свою собственную базу данных, кодовую базу и зависимости. Избегайте совместного использования ресурсов между микросервисами для настоящей изоляции и независимости.
- Оценка связности: Перед созданием нового микросервиса оцените, насколько взаимосвязаны функции, которые он будет выполнять. Объединяйте сильно связанные функции в один микросервис для уменьшения избыточных связей.
Понимание граничных контекстов и разделение функциональности на независимые компоненты являются ключевыми аспектами успешной микросервисной архитектуры. Однако важно сохранить баланс между независимостью и сложностью. Неконтролируемая декомпозиция может привести к проблемам, а избыточная сложность не способствует устойчивости и легкости поддержки системы.
- Антипаттерн "Микросервисный обман"
Проблема этого антипаттерна заключается в иллюзии микросервисности внутри каждого компонента. В микросервисной архитектуре цель заключается в разделении приложения на небольшие автономные сервисы, каждый из которых обладает четко определенной функцией. Однако, когда внутри каждого микросервиса возникает сложная и плотная внутренняя структура, нарушающая принципы независимости, возникает антипаттерн "Микросервисный обман".
Последствия: Эта иллюзия микросервисности внутри компонента ведет к потере главного преимущества микросервисов – независимости. Если внутри каждого микросервиса существует внутренняя структура, тесно связанная с другими компонентами, то возможность независимого обновления, масштабирования и внесения изменений теряется.
Решение: Чтобы избежать "Микросервисного обмана", необходимо придерживаться принципов четкого разделения ответственности и изоляции.
Ниже будет представлен пример на Python, который иллюстрирует антипаттерн "Микросервисный обман".
Рисунок 1. Пример антипаттерна "Микросервисный обман" на Python.
(Источник: https://habr.com/ru/companies/otus/articles/754712/
В этом примере есть два "микросервиса": OrderService и NotificationService. Однако, даже если они выглядят как отдельные компоненты, они фактически имеют сложную внутреннюю структуру и тесную зависимость друг от друга.
Обратите внимание, что в реальной микросервисной архитектуре оба этих компонента должны быть независимыми и иметь минимальную связность. Они не должны сильно зависеть друг от друга и выполнять только свою специфичную функцию.
- Антипаттерн "Синхронные Узлы"
Таблица 1.
Описание антипаттерна "Синхронные Узлы"
(Источник: https://habr.com/ru/companies/otus/articles/754712/
Описание антипатерна |
Последствия |
Способ решения |
Проблема этого антипаттерна связана с применением блокирующей, синхронной коммуникации между микросервисами, что приводит к замедлению системы и увеличению вероятности сбоев. Вместо асинхронной взаимосвязи, микросервисы вызывают друг друга напрямую, блокируя выполнение и ожидая ответа.
|
Синхронная связь между микросервисами снижает производительность и надежность системы. Заблокированные микросервисы приводят к замедлению обработки запросов, делая систему неэффективной. Помимо того, это увеличивает риск сбоев: если один микросервис перестает отвечать, это может привести к каскадным сбоям в других микросервисах.
|
Решение: Чтобы избежать "Синхронных Узлов", необходимо применять асинхронные методы коммуникации: Использование очередей сообщений: Очереди сообщений предоставляют эффективный способ асинхронной коммуникации. Микросервисы могут отправлять сообщения в очередь, и другие микросервисы будут обрабатывать эти сообщения асинхронно. Это улучшает отказоустойчивость и обработку больших объемов данных. Событийно-ориентированный подход: Рассмотрите событийно-ориентированный подход, где микросервисы могут публиковать события, а другие микросервисы могут на них подписываться и реагировать. Это создает более гибкую и масштабируемую архитектуру. |
- Антипаттерн "Избыточное использование общих баз данных"
Таблица 2.
Избыточное использование общих баз данных
(Источник: https://habr.com/ru/companies/otus/articles/754712/)
Описание антипатерна |
Последствия |
Способ устранения |
Создание и поддержка общих баз данных - это явление, которое может оказаться неблагоприятным для микросервисной архитектуры. Этот метод предполагает использование одной общей базы данных для нескольких микросервисов. Вместо того, чтобы каждый микросервис имел свое независимое хранилище данных, они разделяют одну базу данных, что может повлечь за собой серьезные проблемы.
|
Во-первых, если требуется изменить структуру данных для одного микросервиса, необходимо учесть, как это повлияет на другие микросервисы, что значительно усложняет процесс. Во-вторых, возникают проблемы с согласованностью данных. Поскольку несколько микросервисов имеют доступ к одной базе данных, возникают риски непредсказуемых изменений данных другими микросервисами. Это может привести к ошибкам в бизнес-логике, дублированию данных и даже искажению реального состояния системы. |
Чтобы избежать избыточного использования общих баз данных, следует придерживаться подхода, при котором каждый микросервис имеет свою собственную базу данных. Это позволяет микросервисам быть независимыми и отвечать только за свои данные и бизнес-логику.
|
- Антипаттерн "Пренебрежение отказоустойчивостью"
Отказы - это неизбежная часть функционирования любой распределенной системы, включая микросервисы. Однако, некоторые команды уделяют этим событиям недостаточное внимание, не разрабатывая необходимых механизмов для минимизации их влияния.
Пренебрежение отказоустойчивостью может иметь серьезные последствия для системы. Если микросервисы не обеспечивают средства для борьбы с отказами, это может привести к потере данных, недоступности сервисов и даже полной остановке системы. Например, если один из микросервисов перестает отвечать из-за сбоя, это может вызвать каскадный эффект, затрагивая другие зависимые микросервисы. Как результат, клиентские запросы могут остаться без ответа, данные могут быть повреждены или утеряны, а пользователи столкнутся с недоступностью системы.
Решение: внедрение стратегий резервирования, гибкое масштабирование, деградация функциональности. Для избежания данного антипаттерна следует уделить особое внимание разработке механизмов, которые позволят системе успешно справляться с отказами и минимизировать их влияние.
Внедрение стратегий резервирования. Эффективные стратегии резервирования, такие как "Circuit Breaker", позволяют контролировать доступность и отказоустойчивость микросервисов. Эти механизмы автоматически отключают микросервис, если он перестает отвечать, и позволяют гибко управлять трафиком и запросами к нему.
Гибкое масштабирование. Гибкое горизонтальное масштабирование является ключевой частью отказоустойчивости. Это позволяет эффективно управлять большой нагрузкой путем добавления новых экземпляров микросервисов. Такой подход также облегчает замену недоступных или вышедших из строя компонентов.
- Антипаттерн "Пренебрежение мониторингом и диагностикой"
Мониторинг и диагностика – это ключевые компоненты успешной микросервисной архитектуры. Тем не менее, некоторые разработчики и команды могут упустить из виду важность этих аспектов, что ведет к появлению данного антипаттерна. Игнорирование необходимости эффективного мониторинга и диагностики имеет серьезные последствия для системы и бизнеса. Когда проблемы возникают и остаются незамеченными, время восстановления значительно увеличивается. Отсутствие информации о текущем состоянии системы делает процесс выявления и устранения ошибок медленным и неэффективным. Сложности в выявлении проблем также могут привести к неопределенности и ошибочным решениям. Без достаточной информации о происходящем, команде разработчиков сложно точно диагностировать и устранять корневые причины проблем.
Способы устранения:
- Внедрение мониторинговых инструментов. Используйте специализированные мониторинговые инструменты для наблюдения за работой микросервисов и сбора ключевых метрик. Эти инструменты предоставляют информацию о загрузке системы, расходе ресурсов, времени отклика и других важных параметрах.
- Трассировка запросов. Внедрите систему трассировки запросов для отслеживания пути, который проходят запросы от инициирования до завершения в системе. Это поможет выявить узкие места и слабые звенья в производительности системы, а также выявить места, где запросы могут теряться или замедляться.
- Система оповещений. Настройте систему оповещений, которая мгновенно оповещает команду разработчиков о проблемах и сбоях в реальном времени. Алерты могут быть настроены на различные критические события, такие как недоступность сервисов, высокая нагрузка на ресурсы или аномалии в поведении системы. Важно воспринимать мониторинг как непрерывный процесс, который помогает команде разработчиков быстро реагировать на изменения и проблемы. Алерты и метрики мониторинга становятся ценным источником информации для улучшения кода, оптимизации производительности и создания более стабильных и надежных микросервисов [3,4,5,6].
Заключение
Таким образом, понимание архитектуры микросервисов и избегание антипаттернов являются ключевыми для успешной работы. Глубокое понимание проблем, с которыми можно столкнуться, и способы их предотвращения позволяют разрабатывать микросервисы, способные успешно справляться с вызовами реального мира. Неправильное применение этих принципов без должного проектирования может привести к серьезным сложностям в разработке и поддержке системы. Для обеспечения устойчивости микросервисной системы и избежания антипаттернов, необходимо следовать нескольким важным рекомендациям:
- Тщательно планируйте граничные контексты: Определите четкие граничные контексты для каждого микросервиса и поддерживайте их независимость. Тщательное планирование поможет избежать пересечения ответственности и конфликтов между сервисами.
- Разумно декомпозируйте систему: Избегайте создания слишком мелких или слишком крупных микросервисов. Найдите баланс между независимостью и сложностью системы. Слишком мелкие сервисы могут привести к избыточной сложности управления, в то время как слишком крупные могут потерять преимущества независимости.
- Управляйте общими модулями: Если микросервисы разделяют общие компоненты, следите за четким разделением ответственности. Эффективное управление общими модулями поможет избежать конфликтов и обеспечит стабильную работу всех сервисов.
- Используйте асинхронную коммуникацию: Для избежания антипаттерна "Синхронная связь между микросервисами" используйте асинхронные механизмы коммуникации, такие как очереди сообщений. Это позволит уменьшить зависимости между сервисами и обеспечит более гибкую и масштабируемую архитектуру.
Именно поэтому необходимо постоянно совершенствовать архитектуру, учитывать опыт и стремиться к постоянному улучшению, чтобы создать максимально эффективную и стабильную микросервисную систему.
Список литературы:
- Антипаттерны микросервисов. [Электронный ресурс] Режим доступа: https://procodings.ru/dev-ru/antipatterny-mikroservisov/.– (дата обращения 09.10.2023).
- Микросервисная архитектура от А до Я. [Электронный ресурс] Режим доступа: https://axiomjdk.ru/announcements/2021/12/02/microservices-101/.– (дата обращения 09.10.2023).
- Архитектурные антипаттерны в микросервисах и способы их избежания. [Электронный ресурс] Режим доступа: https://habr.com/ru/companies/otus/articles/754712/.– (дата обращения 09.10.2023).
- Антипаттерны проектирования. [Электронный ресурс] Режим доступа: https://habr.com/ru/companies/slurm/articles/706024/.– (дата обращения 09.10.2023).
- Microservices adoption antipatterns. [Электронный ресурс] Режим доступа: https://microservices.io/microservices/antipatterns/-/the/series/2019/06/18/microservices-adoption-antipatterns.html.– (дата обращения 09.10.2023).
- 4 microservices antipatterns that ruin migration. [Электронный ресурс] Режим доступа: https://www.techtarget.com/searchapparchitecture/tip/4-deadly-microservices-antipatterns-that-ruin-migration.– (дата обращения 09.10.2023).