Введение
У распределенных сервисов есть ряд специфических сложностей, несвойственных традиционным монолитным архитектурам. Компоненты распределенных микросервисов находятся на нескольких серверах или даже в разных географических точках, а такая сложная структура требует тщательной проработки и проектирования. Микросервисы выгодно отличаются масштабируемостью и гибкостью, в них проще локализовать неисправность, но зато их сложнее проектировать и эксплуатировать.
Задержка и надежность сети
В распределенных системах сервисы часто взаимодействуют через вызовы по сети, и это становится причиной задержки. Проблемы с сетью могут стать причиной тайм-аутов или невыполнения запросов.
Последствия
Время отклика увеличивается.
Сервис перестает реагировать.
Пример
На одной из платформ для онлайн-торговли микросервисная архитектура используется для управления такими функциями, как администрирование пользователей, работа с каталогом товаров, обработка заказов и платежей, и для каждой из них нужен свой микросервис.
Сложности
Когда пользователь добавляет товар в корзину, front-end service связывается с сервисом продуктов, чтобы собрать подробную информацию, и с сервисом корзины (cart service), чтобы обновить корзину пользователя. Каждый вызов сервиса может выполняться с задержкой, особенно если сервисы находятся в разных географических регионах или сеть перегружена.
Если сервис инвентаризации работает медленно из-за высокой нагрузки или проблем с сетью, то весь процесс оформления заказа может затянуться, в результате чего сервис интерфейса может прервать работу, не получив ответ вовремя, или выдать пользователю сообщение об ошибке.
Стратегии устранения последствий
Внедрить асинхронную связь, чтобы уменьшить количество блокирующих вызовов.
Встроить автоматические выключатели (circuit breaker) для предотвращения каскадных сбоев.
Оптимизировать вызовы сервисов, сократив количество межсервисных взаимодействий.
Согласованность и целостность данных
В распределенных сервисах бывает сложно поддерживать согласованность данных из-за различий в моделях согласованности и нарушений связности сети.
Последствия
Приложение функционирует некорректно из-за несогласованности данных.
Сервисы могут отображать устаревшие данные, если в них не предусмотрена модель согласованности.
Стратегии устранения последствий
Обеспечить согласованность данных между сервисами с помощью распределенных транзакций или паттернов Saga.
Внедрить стратегии управления версиями данных и разрешения конфликтов.
Обнаружение сервисов
Если среда непрерывно меняется (а сервисы в ней постоянно добавляются, удаляются и масштабируются), то обнаружить актуальный экземпляр сервиса довольно сложно.
Последствия
Жестко запрограммированные адреса сервисов могут привести к увеличению затрат на техническое обслуживание.
Из-за простоя сервисов запросы могут оказаться не выполнены, если клиенты не смогут обнаружить доступные экземпляры сервисов.
Стратегии устранения последствий
Использовать для обнаружения сервисов такие инструменты, как Consul, Eureka или встроенные средства Kubernetes.
Использовать балансировщики нагрузки, которые могут в динамическом режиме направлять запросы к доступным экземплярам.
Балансировка нагрузки и управление трафиком
Эффективно распределять входящие запросы между несколькими экземплярами сервисов бывает сложно, особенно в условиях переменной нагрузки.
Последствия
При неравномерном распределении нагрузки одни экземпляры будут перегружены, а другие — недогружены.
Неоптимизированное управление трафиком может привести к проблемам с производительностью.
Стратегии устранения последствий
С помощью интеллектуальных балансировщиков нагрузки перераспределять трафик, исходя из текущей нагрузки, состояния сервисов и географического расстояния до них.
Внедрить автоматическое масштабирование на основе паттернов трафика, чтобы добавлять или удалять экземпляры по мере необходимости.
Вопросы безопасности
Обеспечение безопасности связи между распределенными сервисами может оказаться сложнее, чем в монолитных архитектурах, ведь чем больше точек доступа, тем больше поверхность атаки.
Последствия
Повышенный риск утечки данных и несанкционированного доступа.
Сложности с внедрением согласованных механизмов аутентификации и авторизации.
Стратегии устранения последствий
Использовать HTTPS для безопасного обмена данными между сервисами.
Внедрить OAuth2 или JWT для надежной аутентификации и авторизации.
Использовать шлюзы API для централизации политик безопасности.
Мониторинг и отладка
Из-за большого количества задействованных компонентов отслеживать производительность и состояние распределенных сервисов может оказаться сложнее, чем отдельного приложения.
Последствия
Проблематичность отслеживания запросов между несколькими сервисами может затруднить отладку сложных проблем.
Из-за неполноты картины работы системы некоторые проблемы могут остаться незамеченными.
Стратегии устранения последствий
Внедрить распределенные инструменты трассировки, например, Jaeger или Zipkin, чтобы отслеживать запросы между серверами.
Использовать решения для централизованного журналирования, чтобы объединять журналы из нескольких сервисов (например, ELK Stack).
Отслеживать ключевые показатели производительности с помощью таких инструментов, как Prometheus и Grafana.
Управление конфигурацией
Управлять настройками конфигурации нескольких сервисов может быть трудно, особенно сразу в нескольких средах (dev, pre-prod, prod).
Последствия
Рассогласованные настройки могут повлечь проблемы с развертыванием и неожиданное поведение сервисов.
Ручное управление конфигурацией повышает риск ошибок, вызванных человеческим фактором.
Стратегии устранения последствий
Управлять конфигурациями централизованно с помощью таких инструментов, как Consul или Spring Cloud Config.
Ввести переменные среды или функциональные флаги для динамической настройки.
Переменные среды для динамической настройки:
Настройка переменных среды:
Сложности межсервисных взаимодействий
Выбор протоколов взаимодействия (например, HTTP, gRPC, очереди сообщений) и форматов сериализации (например, JSON, Protobuf) усложняет межсервисное взаимодействие.
Последствия
Несогласованные паттерны взаимодействия могут привести к проблемам интеграции.
Ради выбора конкретного протокола и формата сериализации придется, возможно, поступиться производительностью.
Стратегии устранения последствий
В целях упрощения стандартизировать протоколы взаимодействия между сервисами.
Оценить производительность и избыточные затраты ресурсов на разные форматы сериализации и выбрать наиболее эффективный вариант.
Управление версиями сервисов
С развитием сервиса усложняется управление множеством его версий с одновременным сохранением обратной совместимости.
Последствия
Внезапные изменения могут привести к сбоям в обслуживании клиентов.
Координировать развертывание нескольких сервисов становится сложнее.
Стратегии устранения последствий
Внедрить семантическое управление версиями для четкой передачи информации об изменениях.
Применять сине-зеленое и канареечное развертывания для безопасного релиза новых версий.
Заключение
Работа с распределенными сервисами — это нетривиальная задача, которая требует тщательного планирования, новых внедрений и непрерывного управления, чтобы система работала эффективно и надежно. Применяя лучшие практики и стратегии для решения каждой отдельной задачи, компании смогут создавать надежные и масштабируемые распределенные системы, которые отвечают их бизнес-потребностям. Если спланировать действия заранее, можно повысить отказоустойчивость и производительность распределенных микросервисных архитектур.
OlegZH
Здесь очень не хватает предварительного описания каждого сервиса. Надо понять, зачем нужен конкретный сервис. (А не то, чтобы сервис есть, потому как архитектура такая!)
На первый взгляд, корзина — это просто некое хранилище. Что корзина может делать такого?
А что делает этот сервис?