Шаблон современного веб-приложения для Java

Служба приложений Azure
Azure Front Door
Кэш Azure для Redis

В этой статье показано, как реализовать шаблон современного веб-приложения. Шаблон современного веб-приложения определяет, как модернизировать веб-приложения в облаке и представить архитектуру, ориентированную на обслуживание. Шаблон современного веб-приложения предоставляет предписную архитектуру, код и рекомендации по настройке, которые соответствуют принципам Azure Well-Architected Framework и построению на основе шаблона Reliable Web App.

Почему используйте шаблон современного веб-приложения?

Шаблон современного веб-приложения помогает оптимизировать области веб-приложения с высоким спросом. Он предлагает подробные рекомендации по устранению этих областей, обеспечивая независимое масштабирование для оптимизации затрат. Этот подход позволяет выделять выделенные ресурсы критически важным компонентам, повышая общую производительность. Разреженные службы могут повысить надежность, предотвращая замедление работы в одной части приложения, влияя на других пользователей и обеспечивая независимое управление версиями отдельных компонентов приложения.

Реализация шаблона современного веб-приложения

В этой статье содержатся рекомендации по архитектуре, коду и настройке для реализации шаблона современного веб-приложения. Чтобы перейти к нужному руководству, воспользуйтесь следующими ссылками:

  • Руководство по архитектуре. Узнайте, как модульизировать компоненты веб-приложения и выбрать соответствующую платформу в качестве службы (PaaS).
  • Руководство по коду. Реализация четырех шаблонов проектирования для оптимизации разделенных компонентов: Strangler Fig, выравнивания нагрузки на основе очередей, конкурирующих потребителей и шаблонов мониторинга конечных точек работоспособности.
  • Руководство по настройке: настройка проверки подлинности, авторизации, автомасштабирования и контейнеризации для компонентов, разделенных.

Совет

Логотип GitHub Существует эталонная реализация (пример приложения) шаблона современного веб-приложения. Он представляет конечное состояние реализации современного веб-приложения. Это рабочее веб-приложение, которое содержит все обновления кода, архитектуры и конфигурации, рассмотренные в этой статье. Развертывание и использование эталонной реализации для реализации шаблона современного веб-приложения.

Руководство по архитектуре

Шаблон современного веб-приложения основан на шаблоне Reliable Web App. Для реализации требуется несколько дополнительных архитектурных компонентов. Вам нужна очередь сообщений, платформа контейнеров, служба хранилища и реестр контейнеров (см. рисунок 1).

Схема, показывающая базовую архитектуру шаблона современного веб-приложения.Рис. 1. Основные архитектурные элементы шаблона современного веб-приложения.

Для более высокого уровня обслуживания (SLO) можно добавить второй регион в архитектуру веб-приложения. Настройте подсистему балансировки нагрузки для маршрутизации трафика во второй регион для поддержки активной или пассивной конфигурации в зависимости от бизнес-потребности. Для двух регионов требуются одни и те же службы, кроме одного региона, есть виртуальная сеть концентратора, которая подключается. Применяйте топологию сети концентратора и периферийной сети для централизованной и совместной работы с ресурсами, например брандмауэром сети. Доступ к репозиторию контейнеров через виртуальную сеть концентратора. Если у вас есть виртуальные машины, добавьте узел бастиона в виртуальную сеть концентратора для безопасного управления ими (см. рис. 2).

Схема, показывающая архитектуру шаблона современного веб-приложения со второй областью и топологией сети с концентраторами и периферийными сетями.Рис. 2. Архитектура шаблона современного веб-приложения со второй областью и топологией сети с концентратором и периферийной сетью.

Архитектура decouple

Чтобы реализовать шаблон современного веб-приложения, необходимо разделить существующую архитектуру веб-приложения. Разбиение архитектуры включает разбиение монолитного приложения на небольшие независимые службы, каждая из которых отвечает за определенную функцию или функциональные возможности. Этот процесс подразумевает оценку текущего веб-приложения, изменение архитектуры и, наконец, извлечение кода веб-приложения на платформу контейнеров. Цель заключается в систематическом определении и извлечении служб приложений, которые пользуются наибольшим преимуществом от разложения. Чтобы разделить архитектуру, следуйте приведенным ниже рекомендациям.

  • Определите границы служб, применяйте принципы проектирования на основе домена, чтобы определить ограниченные контексты в монолитном приложении. Каждый ограниченный контекст представляет логическую границу и может быть кандидатом на отдельную службу. Службы, представляющие различные бизнес-функции и имеющие меньше зависимостей, являются хорошими кандидатами на развязку.

  • Оцените преимущества службы. Сосредоточьтесь на службах, которые пользуются большей частью независимого масштабирования. Например, внешняя зависимость, например поставщик услуг электронной почты в бизнес-приложении, может потребовать большей изоляции от сбоя. Рассмотрим службы, которые проходят частые обновления или изменения. Развязывание этих служб позволяет независимому развертыванию и снижает риск влияния на другие части приложения.

  • Оцените техническое обоснование. Изучите текущую архитектуру, чтобы определить технические ограничения и зависимости, которые могут повлиять на процесс развязывания. Планирование управления и совместного использования данных между службами. Несоединяемые службы должны управлять собственными данными и свести к минимуму прямой доступ к базе данных через границы службы.

  • Развертывание служб Azure. Выберите и разверните службы Azure, необходимые для поддержки службы веб-приложений, для извлечения. Используйте следующий раздел "Выбрать правильный раздел служб Azure" для получения рекомендаций.

  • Отделять службу веб-приложений. Определите четкие интерфейсы и API для недавно извлеченных служб веб-приложений для взаимодействия с другими частями системы. Разработка стратегии управления данными, которая позволяет каждой службе управлять собственными данными, обеспечивая согласованность и целостность. Сведения о конкретных стратегиях реализации и шаблонах проектирования, используемых во время этого процесса извлечения, см. в разделе руководства по коду.

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

  • Реализуйте отдельные конвейеры развертывания для каждой отдельной службы. Отдельные конвейеры развертывания позволяют обновлять каждую службу по своему темпу. Если разные команды или организации в вашей компании имеют разные службы, то отдельные конвейеры развертывания предоставляют каждому команду контроль над собственными развертываниями. Используйте средства непрерывной интеграции и непрерывной доставки (CI/CD), такие как Jenkins, GitHub Actions или Azure Pipelines для настройки этих конвейеров.

  • Изменение элементов управления безопасностью. Убедитесь, что элементы управления безопасностью обновлены для учетной записи новой архитектуры, включая правила брандмауэра и элементы управления доступом.

Выберите нужные службы Azure

Для каждой службы Azure в архитектуре обратитесь к соответствующему руководству по службе Azure в хорошо спроектированной платформе. Для шаблона современного веб-приложения требуется система обмена сообщениями для поддержки асинхронного обмена сообщениями, платформы приложений, поддерживающей контейнеризацию и репозиторий образов контейнеров.

  • Выберите очередь сообщений. Очередь сообщений — это важная часть архитектуры, ориентированной на обслуживание. Он отделяет отправителей сообщений и получателей для включения асинхронного обмена сообщениями. Используйте рекомендации по выбору службы обмена сообщениями Azure, чтобы выбрать систему обмена сообщениями Azure, которая поддерживает ваши потребности в проектировании. В Azure есть три службы обмена сообщениями: Сетка событий Azure, Центры событий Azure и служебная шина. Начните с служебная шина в качестве выбора по умолчанию и используйте другие два варианта, если служебная шина не соответствует вашим потребностям.

    Service Вариант использования
    Cлужебная шина Выберите служебная шина для надежной, упорядоченной и, возможно, транзакционной доставки сообщений с высоким уровнем ценности в корпоративных приложениях.
    Сетка событий Выберите сетку событий, когда необходимо эффективно обрабатывать большое количество дискретных событий. Сетка событий масштабируется для приложений, управляемых событиями, в которых требуется перенаправить множество небольших независимых событий (например, изменений состояния ресурсов) подписчикам в модели с низкой задержкой, модель публикации и подписки.
    Event Hubs Выберите Центры событий для массового приема данных с высокой пропускной способностью, например телеметрии, журналов или аналитики в режиме реального времени. Центры событий оптимизированы для сценариев потоковой передачи, в которых массовые данные должны обрабатываться и обрабатываться непрерывно.
  • Реализуйте службу контейнеров. Для частей приложения, которые требуется контейнеризировать, требуется платформа приложений, поддерживающая контейнеры. Используйте руководство по выбору службы контейнеров Azure для принятия решения. В Azure есть три основных службы контейнеров: приложения контейнеров Azure, Служба Azure Kubernetes (AKS) и служба приложение Azure. Начните с контейнерных приложений в качестве варианта по умолчанию и используйте другие два варианта, если контейнерные приложения не соответствуют вашим потребностям.

    Service Вариант использования
    Контейнеры приложений Выберите контейнерные приложения, если вам нужна бессерверная платформа, которая автоматически масштабирует контейнеры и управляет контейнерами в приложениях на основе событий.
    AKS Выберите AKS, если вам нужен подробный контроль над конфигурациями Kubernetes и расширенными функциями масштабирования, сети и безопасности.
    веб-приложения для контейнера Выберите веб-приложение для контейнеров в Служба приложений для простого интерфейса PaaS.
  • Реализуйте репозиторий контейнеров. При использовании любой вычислительной службы на основе контейнеров необходимо иметь репозиторий для хранения образов контейнеров. Вы можете использовать общедоступный реестр контейнеров, например Docker Hub или управляемый реестр, например Реестр контейнеров Azure. Чтобы принять решение, используйте общие сведения о реестрах контейнеров в Azure.

Руководство по коду

Чтобы успешно разделить и извлечь независимую службу, необходимо обновить код веб-приложения со следующими шаблонами конструктора: шаблон Strangler Fig, шаблон выравнивания нагрузки на основе очередей, шаблон конкурирующих потребителей, шаблон мониторинга конечных точек работоспособности и шаблон повторных попыток.

Схема, показывающая роль шаблонов проектирования в архитектуре шаблона современного веб-приложения.Рис. 3. Роль шаблонов проектирования.

  1. Шаблон Strangler Fig: шаблон Strangler Fig добавочно переносит функциональные возможности из монолитного приложения в службу, разделенную. Реализуйте этот шаблон в основном веб-приложении для постепенной миграции функций в независимые службы путем направления трафика на основе конечных точек.

  2. Шаблон выравнивания нагрузки на основе очередей: шаблон выравнивания нагрузки на основе очередей управляет потоком сообщений между производителем и потребителем с помощью очереди в качестве буфера. Реализуйте этот шаблон в части производителя отдельной службы для асинхронного управления потоком сообщений с помощью очереди.

  3. Шаблон конкурирующих потребителей: шаблон конкурирующих потребителей позволяет нескольким экземплярам развязанной службы независимо считывать из одной очереди сообщений и конкурировать с обработкой сообщений. Реализуйте этот шаблон в развязанной службе для распределения задач между несколькими экземплярами.

  4. Шаблон мониторинга конечных точек работоспособности: шаблон мониторинга конечных точек работоспособности предоставляет конечные точки для мониторинга состояния и работоспособности различных частей веб-приложения. (4a) Реализуйте этот шаблон в основном веб-приложении. (4b) Кроме того, реализуйте его в отдельной службе для отслеживания работоспособности конечных точек.

  5. Шаблон повторных попыток: шаблон повторных попыток обрабатывает временные сбои путем повторения операций, которые могут периодически завершаться ошибкой. (5a) Реализуйте этот шаблон во всех исходящих вызовах других служб Azure в основном веб-приложении, таких как вызовы очереди сообщений и частные конечные точки. (5b) Кроме того, реализуйте этот шаблон в отдельной службе для обработки временных сбоев в вызовах частных конечных точек.

Каждый шаблон проектирования предоставляет преимущества, которые соответствуют одному или нескольким столпам платформы Well-Architected Framework (см. следующую таблицу).

Конструктивный шаблон Расположение реализации Надежность (RE) Безопасность (SE) Оптимизация затрат (CO) Операционное превосходство (OE) Эффективность производительности (PE) Поддержка принципов хорошо спроектированной платформы
Шаблон Strangler Fig Основное веб-приложение RE:08
CO:07
CO:08
OE:06
OE:11
Шаблон балансировки нагрузки на основе очередей Производитель развязанной службы RE:06
RE:07
CO:12
PE:05
Шаблон конкурирующих потребителей Отсоединяемая служба RE:05
RE:07
CO:05
CO:07
PE:05
PE:07
Шаблон мониторинга конечных точек работоспособности Основное веб-приложение и несоединяемая служба RE:07
RE:10
OE:07
PE:05
Шаблон повторных попыток Основное веб-приложение и несоединяемая служба RE:07

Реализация шаблона Strangler Fig

Используйте шаблон Strangler fig для постепенной миграции функций из монолитной базы кода в новые независимые службы. Извлеките новые службы из существующей монолитной базы кода и медленно модернизируйте критически важные части веб-приложения. Чтобы реализовать шаблон Strangler Fig, следуйте приведенным ниже рекомендациям.

  • Настройка уровня маршрутизации. В базе кода монолитного веб-приложения реализуйте уровень маршрутизации, который направляет трафик на основе конечных точек. Используйте пользовательскую логику маршрутизации при необходимости для обработки конкретных бизнес-правил для направления трафика. Например, если у вас есть конечная /users точка в монолитном приложении и вы переместили эту функцию в развязанную службу, уровень маршрутизации направляет все запросы к /users новой службе.

  • Управление развертыванием компонентов. Реализуйте флаги функций и поэтапное развертывание для постепенного развертывания разложенных служб. Существующая монолитная маршрутизация приложений должна контролировать количество запросов, получаемых несвязанными службами. Начните с небольшого процента запросов и увеличение использования с течением времени, так как вы получаете уверенность в его стабильности и производительности.

    Например, эталонная реализация извлекает функциональные возможности доставки электронной почты в автономную службу, которая может постепенно применяться для обработки большей части запросов на отправку сообщений электронной почты, содержащих руководства по поддержке Contoso. Так как новая служба подтверждает свою надежность и производительность, она в конечном итоге может взять на себя весь набор обязанностей электронной почты от монолита, завершив переход.

  • Используйте службу фасада (при необходимости). Служба фасада полезна, если один запрос должен взаимодействовать с несколькими службами или когда требуется скрыть сложность базовой системы от клиента. Однако если у службы, разделенной, нет общедоступных API- интерфейсов, служба фасада может не потребоваться.

    В базе кода монолитного веб-приложения реализуйте службу фасада для маршрутизации запросов в соответствующую серверную часть (монолит или микрослужбу). В новой отдельной службе убедитесь, что новая служба может обрабатывать запросы независимо при доступе через фасад.

Реализация шаблона выравнивания нагрузки на основе очередей

Реализуйте шаблон выравнивания нагрузки на основе очередей в части производителя отсоединяемой службы для асинхронной обработки задач, которые не нуждаются в немедленном ответе. Этот шаблон повышает общую скорость реагирования системы и масштабируемость с помощью очереди для управления распределением рабочих нагрузок. Она позволяет отсоединяемой службе обрабатывать запросы по согласованной скорости. Чтобы эффективно реализовать этот шаблон, следуйте приведенным ниже рекомендациям.

  • Используйте очередь сообщений без блокировки. Убедитесь, что процесс, отправляющий сообщения в очередь, не блокирует другие процессы, ожидая отсоединяемой службы для обработки сообщений в очереди. Если для процесса требуется результат операции отсоединяемой службы, реализуйте альтернативный способ обработки ситуации, ожидая завершения операции в очереди. Например, в Spring Boot класс можно использовать StreamBridge для асинхронной публикации сообщений в очередь без блокировки вызывающего потока (см. пример кода):

    private final StreamBridge streamBridge;
    
    public SupportGuideQueueSender(StreamBridge streamBridge) {
        this.streamBridge = streamBridge;
    }
    
    // Asynchronously publish a message without blocking the calling thread
    @Override
    public void send(String to, String guideUrl, Long requestId) {
        EmailRequest emailRequest = EmailRequest.newBuilder()
                .setRequestId(requestId)
                .setEmailAddress(to)
                .setUrlToManual(guideUrl)
                .build();
    
        log.info("EmailRequest: {}", emailRequest);
    
        var message = emailRequest.toByteArray();
        streamBridge.send(EMAIL_REQUEST_QUEUE, message);
    
        log.info("Message sent to the queue");
    }
    

    В этом примере Java используется StreamBridge для асинхронной отправки сообщений. Этот подход гарантирует, что основное приложение остается адаптивным и может одновременно обрабатывать другие задачи, в то время как отсоединяемая служба обрабатывает очереди запросов с управляемой скоростью.

  • Реализация повторных попыток и удаления сообщений. Реализуйте механизм для повторной обработки очередных сообщений, которые невозможно обработать успешно. Если сбои сохраняются, эти сообщения следует удалить из очереди. Например, служебная шина имеет встроенные функции повторных попыток и очереди недоставленных писем.

  • Настройте идемпотентную обработку сообщений. Логика, которая обрабатывает сообщения из очереди, должна быть идемпотентной для обработки случаев, когда сообщение может обрабатываться более одного раза. В Spring Boot можно использовать или @KafkaListener с @StreamListener уникальным идентификатором сообщения, чтобы предотвратить повторную обработку. Или можно упорядочить бизнес-процесс для работы в функциональном подходе с Spring Cloud Stream, где consume метод определяется таким образом, что приводит к тому же результату при многократном выполнении. Прочитайте Spring Cloud Stream с служебная шина для дальнейшего списка параметров, которые управляют поведением использования сообщений.

  • Управление изменениями в интерфейсе. Асинхронная обработка может привести к тому, что задачи не выполняются немедленно. Пользователи должны знать, когда их задача по-прежнему обрабатывается, чтобы задать правильные ожидания и избежать путаницы. Используйте визуальные подсказки или сообщения, чтобы указать, что выполняется задача. Предоставьте пользователям возможность получать уведомления при выполнении задачи, например сообщение электронной почты или push-уведомление.

Реализация шаблона конкурирующих потребителей

Реализуйте шаблон конкурирующих потребителей в развязанной службе для управления входящими задачами из очереди сообщений. Этот шаблон включает распределение задач между несколькими экземплярами развязанных служб. Эти службы обрабатывают сообщения из очереди, повышая балансировку нагрузки и повышая емкость системы для обработки одновременных запросов. Шаблон конкурирующих потребителей действует в следующих случаях:

  • Последовательность обработки сообщений не имеет решающего значения.
  • Очередь по-прежнему не влияет на неправильно сформированные сообщения.
  • Операция обработки идемпотентна, то есть она может применяться несколько раз, не изменяя результат за пределами первоначального приложения.

Чтобы реализовать шаблон конкурирующих потребителей, следуйте приведенным ниже рекомендациям.

  • Обработка параллельных сообщений. При получении сообщений из очереди убедитесь, что система масштабируется предсказуемо, настроив параллелизм для соответствия системному проектированию. Результаты нагрузочного теста помогают определить соответствующее количество одновременных сообщений, которые будут обрабатываться, и вы можете начать с одного, чтобы оценить, как работает система.

  • Отключите предварительную выборку. Отключите предварительную выборку сообщений, чтобы потребители только извлекали сообщения, когда они будут готовы.

  • Используйте режимы надежной обработки сообщений. Используйте режим надежной обработки, например PeekLock (или его эквивалент), который автоматически повторяет сообщения, которые завершаются сбоем. Этот режим повышает надежность по сравнению с методами удаления. Если не удается обработать сообщение, другой должен иметь возможность обрабатывать его без ошибок, даже если сообщение обрабатывается несколько раз.

  • Реализуйте обработку ошибок. Перенаправите неправильные или необработанные сообщения в отдельную очередь недоставленных сообщений. Эта конструкция предотвращает повторяющуюся обработку. Например, можно перехватывать исключения во время обработки сообщений и перемещать проблемное сообщение в отдельную очередь. Для служебная шина сообщения перемещаются в очередь недоставленных разрешений после указанного количества попыток доставки или явного отклонения приложением.

  • Обработка сообщений вне порядка. Разработка потребителей для обработки сообщений, поступающих из последовательности. Несколько параллельных потребителей означает, что они могут обрабатывать сообщения вне порядка.

  • Масштабирование на основе длины очереди. Службы, потребляющие сообщения из очереди, должны автомасштабироваться на основе длины очереди. Автомасштабирование на основе масштабирования на основе масштабирования позволяет эффективно обрабатывать пики входящих сообщений.

  • Используйте очередь ответа на сообщение. Если системе требуются уведомления для обработки сообщений после сообщения, настройте выделенную очередь ответа или ответа. Эта настройка разделяет операционные сообщения от процессов уведомлений.

  • Используйте службы без отслеживания состояния. Рассмотрите возможность использования служб без отслеживания состояния для обработки запросов из очереди. Это позволяет легко масштабировать и эффективно использовать ресурсы.

  • Настройка ведения журнала. Интегрируйте ведение журнала и обработку конкретных исключений в рабочий процесс обработки сообщений. Сосредоточьтесь на захвате ошибок сериализации и перенаправлении этих проблемных сообщений в механизм недоставленных букв. Эти журналы предоставляют ценные аналитические сведения для устранения неполадок.

Например, эталонная реализация использует шаблон конкурирующих потребителей в службе без отслеживания состояния, работающей в контейнерных приложениях, для обработки запросов на доставку электронной почты из очереди служебная шина.

Обработчик записывает сведения о обработке сообщений, помогая в устранении неполадок и мониторинге. Он фиксирует ошибки десериализации и предоставляет аналитические сведения, необходимые при отладке процесса. Служба масштабируется на уровне контейнера, что позволяет эффективно обрабатывать пики сообщений на основе длины очереди (см. следующий код).

@Configuration
public class EmailProcessor {

    private static final Logger log = LoggerFactory.getLogger(EmailProcessor.class);

    @Bean
    Function<byte[], byte[]> consume() {
        return message -> {

            log.info("New message received");

            try {
                EmailRequest emailRequest = EmailRequest.parseFrom(message);
                log.info("EmailRequest: {}", emailRequest);

                EmailResponse emailResponse = EmailResponse.newBuilder()
                        .setEmailAddress(emailRequest.getEmailAddress())
                        .setUrlToManual(emailRequest.getUrlToManual())
                        .setRequestId(emailRequest.getRequestId())
                        .setMessage("Email sent to " + emailRequest.getEmailAddress() + " with URL to manual " + emailRequest.getUrlToManual())
                        .setStatus(Status.SUCCESS)
                        .build();

                return emailResponse.toByteArray();

            } catch (InvalidProtocolBufferException e) {
                throw new RuntimeException("Error parsing email request message", e);
            }
        };
    }
}

Реализация шаблона мониторинга конечной точки работоспособности

Реализуйте шаблон мониторинга конечных точек работоспособности в основном коде приложения и отсоедините код службы для отслеживания работоспособности конечных точек приложения. Оркестраторы, такие как AKS или контейнерные приложения, могут опрашивать эти конечные точки, чтобы проверить работоспособность службы и перезапустить неработоспособные экземпляры. Spring Boot обеспечивает встроенную поддержку проверок работоспособности с помощью Spring Boot Actuator, которая может предоставлять конечные точки проверки работоспособности для ключевых зависимостей, таких как базы данных, брокеры сообщений и системы хранения. Чтобы реализовать шаблон мониторинга конечных точек работоспособности, выполните следующие рекомендации.

  • Реализуйте проверки работоспособности. Используйте Spring Boot Actuator для предоставления конечных точек проверки работоспособности. Spring Boot Actuator предоставляет конечную точку /actuator/health , которая включает встроенные индикаторы работоспособности и пользовательские проверки для различных зависимостей. Чтобы включить конечную spring-boot-starter-actuator точку работоспособности, добавьте зависимость в файл или build.gradle файлpom.xml.

    <!-- Add Spring Boot Actuator dependency -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    

    Настройте конечную точку работоспособности, как показано в application.properties эталонной реализации: txt management.endpoints.web.exposure.include=metrics,health,info,retry,retryevents

  • Проверка зависимостей. Spring Boot Actuator включает индикаторы работоспособности для различных зависимостей, таких как базы данных, брокеры сообщений (RabbitMQ или Kafka) и службы хранения. Чтобы проверить доступность служб Azure, таких как Хранилище BLOB-объектов Azure или служебная шина, используйте подключаемые модули сообщества, такие как Azure Spring Apps или интеграции Micrometer, которые предоставляют индикаторы работоспособности для этих служб. Если требуются пользовательские проверки, их можно реализовать, создав настраиваемую HealthIndicator фасоль.

    import org.springframework.boot.actuate.health.Health;
    import org.springframework.boot.actuate.health.HealthIndicator;
    import org.springframework.stereotype.Component;
    
    @Component
    public class CustomAzureServiceBusHealthIndicator implements HealthIndicator {
        @Override
        public Health health() {
            // Implement your health check logic here (e.g., ping Service Bus)
            boolean isServiceBusHealthy = checkServiceBusHealth();
            return isServiceBusHealthy ? Health.up().build() : Health.down().build();
        }
    
        private boolean checkServiceBusHealth() {
            // Implement health check logic (pinging or connecting to the service)
            return true; // Placeholder, implement actual logic
        }
    }
    
  • Настройте ресурсы Azure. Настройте ресурс Azure для использования URL-адресов проверки работоспособности приложения для подтверждения активности и готовности. Например, с помощью Terraform можно использовать URL-адреса проверки работоспособности для подтверждения активности и готовности приложений, развернутых в контейнерных приложениях. Дополнительные сведения см. в разделе "Пробы работоспособности" в контейнерных приложениях.

Реализация шаблона повторных попыток

Шаблон повторных попыток позволяет приложениям восстанавливаться после временных сбоев. Шаблон повторных попыток является центральным шаблоном Надежных веб-приложений, поэтому веб-приложение должно использовать шаблон повторных попыток. Примените шаблон повторных попыток к запросам к системам обмена сообщениями и запросам, выданным несвязанными службами, извлеченными из веб-приложения. Чтобы реализовать шаблон повторных попыток, следуйте приведенным ниже рекомендациям.

  • Настройка параметров повтора. При интеграции с очередью сообщений убедитесь, что клиент отвечает за взаимодействие с очередью с соответствующими параметрами повторных попыток. Укажите такие параметры, как максимальное число повторных попыток, задержка между повторными попытками и максимальной задержкой.

  • Используйте экспоненциальную обратную передачу. Реализуйте экспоненциальную стратегию обратного выхода для повторных попыток. Это означает увеличение времени между каждым повтором экспоненциально, что помогает снизить нагрузку на систему в периоды высоких показателей сбоев.

  • Используйте функцию повторных попыток пакета SDK. Для служб с специализированными пакетами SDK, такими как служебная шина или хранилище BLOB-объектов, используйте встроенные механизмы повторных попыток. Встроенные механизмы повторных попыток оптимизированы для типичных вариантов использования службы и могут эффективно обрабатывать повторные попытки с меньшей конфигурацией, необходимой для вашей части.

  • Внедрение стандартных библиотек устойчивости для клиентов HTTP. Для http-клиентов можно использовать устойчивость4* вместе с RestTemplate spring или WebClient для обработки повторных попыток в связи HTTP. RestTemplate Spring можно упаковать с помощью логики повтора устойчивости 4j для эффективной обработки временных ошибок HTTP.

  • Обработка блокировки сообщений. Для систем на основе сообщений реализуйте стратегии обработки сообщений, поддерживающие повторные попытки без потери данных, такие как использование режимов "просмотр-блокировка" в тех случаях, когда они доступны. Убедитесь, что неудачные сообщения извлекаются эффективно и перемещаются в очередь недоставленных писем после повторяющихся сбоев.

Руководство по настройке

В следующих разделах приведены рекомендации по реализации обновлений конфигурации. Каждый раздел соответствует одному или нескольким основам хорошо спроектированной платформы.

Настройка Надежность (RE) Безопасность (SE) Оптимизация затрат (CO) Операционное превосходство (OE) Эффективность производительности (PE) Поддержка принципов хорошо спроектированной платформы
Настройка проверки подлинности и авторизации SE:05
OE:10
Реализация независимого автомасштабирования RE:06
CO:12
PE:05
Развертывание службы containerize CO:13
PE:09
PE:03

Настройка проверки подлинности и авторизации

Чтобы настроить проверку подлинности и авторизацию для любых новых служб Azure (удостоверений рабочей нагрузки), добавляемого в веб-приложение, выполните следующие рекомендации.

  • Используйте управляемые удостоверения для каждой новой службы. Каждая независимая служба должна иметь собственное удостоверение и использовать управляемые удостоверения для проверки подлинности между службами. Управляемые удостоверения устраняют необходимость управления учетными данными в коде и снижают риск утечки учетных данных. Это помогает избежать размещения конфиденциальных данных, таких как строка подключения в файлах кода или конфигурации.

  • Предоставьте минимальные привилегии каждой новой службе. Назначьте только необходимые разрешения каждому новому удостоверению службы. Например, если удостоверение должно отправляться только в реестр контейнеров, не предоставляйте ему разрешения на вытягивание. Регулярно просматривайте эти разрешения и корректируйте их по мере необходимости. Используйте разные удостоверения для разных ролей, таких как развертывание и приложение. Это ограничивает потенциальный ущерб, если одно удостоверение скомпрометировано.

  • Внедрение инфраструктуры в качестве кода (IaC). Используйте средства Bicep или аналогичные средства IaC, такие как Terraform, для определения облачных ресурсов и управления ими. IaC обеспечивает согласованное применение конфигураций безопасности в развертываниях и позволяет управлять версиями настройки инфраструктуры.

Чтобы настроить проверку подлинности и авторизацию для пользователей (удостоверений пользователей), выполните следующие рекомендации.

  • Предоставьте пользователям наименьшие привилегии. Как и в службах, убедитесь, что пользователи получают только разрешения, необходимые им для выполнения задач. Регулярно просматривайте и настраивайте эти разрешения.

  • Проводите регулярные аудиты безопасности. Регулярно просматривайте и проверяйте настройку безопасности. Найдите какие-либо неправильные настройки или ненужные разрешения и немедленно исправьте их.

Эталонная реализация использует IaC для назначения управляемых удостоверений добавленным службам и определенным ролям для каждого удостоверения. Он определяет роли и разрешения для развертывания путем определения ролей для отправки и извлечения реестра контейнеров (см. следующий код).

resource "azurerm_role_assignment" "container_app_acr_pull" {
  principal_id         = var.aca_identity_principal_id
  role_definition_name = "AcrPull"
  scope                = azurerm_container_registry.acr.id
}

resource "azurerm_user_assigned_identity" "container_registry_user_assigned_identity" {
  name                = "ContainerRegistryUserAssignedIdentity"
  resource_group_name = var.resource_group
  location            = var.location
}

resource "azurerm_role_assignment" "container_registry_user_assigned_identity_acr_pull" {
  scope                = azurerm_container_registry.acr.id
  role_definition_name = "AcrPull"
  principal_id         = azurerm_user_assigned_identity.container_registry_user_assigned_identity.principal_id
}


# For demo purposes, allow current user access to the container registry
# Note: when running as a service principal, this is also needed
resource "azurerm_role_assignment" "acr_contributor_user_role_assignement" {
  scope                = azurerm_container_registry.acr.id
  role_definition_name = "Contributor"
  principal_id         = data.azuread_client_config.current.object_id
}

Настройка независимого автомасштабирования

Шаблон современного веб-приложения начинает разбиение монолитной архитектуры и представляет разбиение службы. Если вы отделяете архитектуру веб-приложения, можно масштабировать отдельные службы независимо друг от друга. Масштабирование служб Azure для поддержки независимой службы веб-приложений, а не всего веб-приложения, оптимизирует затраты на масштабирование во время удовлетворения требований. Чтобы выполнить автомасштабирование контейнеров, следуйте приведенным ниже рекомендациям.

  • Используйте службы без отслеживания состояния. Убедитесь, что службы без отслеживания состояния. Если веб-приложение содержит состояние сеанса в процессе, внешний его в распределенный кэш, например Redis или базу данных, например SQL Server.

  • Настройте правила автомасштабирования. Используйте конфигурации автомасштабирования, которые обеспечивают наиболее экономичный контроль над службами. Для контейнерных служб масштабирование на основе событий, например автомасштабирование на основе событий Kubernetes (KEDA), часто обеспечивает детализированный контроль, позволяющий масштабироваться на основе метрик событий. Контейнерные приложения и AKS поддерживают KEDA. Для служб, которые не поддерживают KEDA, например Служба приложений, используйте функции автомасштабирования, предоставляемые самой платформой. Эти функции часто включают масштабирование на основе правил на основе метрик или HTTP-трафика.

  • Настройте минимальные реплики. Чтобы предотвратить холодный запуск, настройте параметры автомасштабирования для поддержания как минимум одной реплики. Холодный запуск — это при инициализации службы из остановленного состояния, которое часто создает отложенный ответ. Если минимизация затрат является приоритетом, и вы можете терпеть задержки холодного запуска, задайте минимальное число реплик равным 0 при настройке автомасштабирования.

  • Настройте период охлаждения. Примените соответствующий период охлаждения, чтобы ввести задержку между событиями масштабирования. Цель состоит в том, чтобы предотвратить чрезмерное масштабирование действий, вызванных временными пиками нагрузки.

  • Настройте масштабирование на основе очередей. Если приложение использует очередь сообщений, например служебная шина, настройте параметры автомасштабирования для масштабирования на основе длины очереди с сообщениями запроса. Масштабировщик предназначен для поддержания одной реплики службы для каждого N-сообщения в очереди (округлено).

Например, эталонная реализация использует масштабировщик KEDA служебная шина для автоматического масштабирования приложения-контейнера на основе длины очереди служебная шина. Правило масштабирования с именем service-bus-queue-length-ruleнастраивает количество реплик служб в зависимости от количества сообщений в указанной очереди служебная шина. Параметр messageCount имеет значение 10, что означает, что масштабировщик добавляет одну реплику для каждых 10 сообщений в очереди. Максимальные реплики (max_replicas) имеют значение 10, а минимальные реплики неявно равны 0, если не переопределено, что позволяет службе уменьшить до нуля, если в очереди нет сообщений. Строка подключения для очереди служебная шина хранится безопасно в качестве секрета в Azure, который azure-servicebus-connection-stringиспользуется для проверки подлинности масштабировщика в служебная шина.

    max_replicas = 10
    min_replicas = 1

    custom_scale_rule {
      name             = "service-bus-queue-length-rule"
      custom_rule_type = "azure-servicebus"
      metadata = {
        messageCount = 10
        namespace    = var.servicebus_namespace
        queueName    = var.email_request_queue_name
      }
      authentication {
        secret_name       = "azure-servicebus-connection-string"
        trigger_parameter = "connection"
      }
    }

Развертывание службы containerize

Контейнеризация означает, что все зависимости для функции приложения инкапсулируются в упрощенном образе, который можно надежно развернуть в широком диапазоне узлов. Чтобы контейнеризировать развертывание, выполните следующие рекомендации.

  • Определите границы домена. Начните с идентификации границ домена в монолитном приложении. Это помогает определить, какие части приложения можно извлечь в отдельные службы.

  • Создание образов Docker. При создании образов Docker для служб Java используйте официальные базовые образы OpenJDK. Эти образы содержат только минимальный набор пакетов, необходимых для выполнения Java, что сводит к минимуму размер пакета и область области атаки.

  • Используйте многоэтапные файлы Dockerfile. Используйте многоэтапные файлы Dockerfile для разделения ресурсов во время сборки из образа контейнера среды выполнения. Это помогает сохранить рабочие образы небольшими и безопасными. Вы также можете использовать предварительно настроенный сервер сборки и скопировать JAR-файл в образ контейнера.

  • Запуск от имени пользователя, не являемого пользователем. Запустите контейнеры Java как пользователя, не являющегося пользователем (с помощью имени пользователя или UID, $APP_UID), чтобы соответствовать принципу наименьших привилегий. Он ограничивает потенциальные последствия скомпрометированного контейнера.

  • Прослушивание порта 8080. При запуске от имени пользователя, отличного от работы, настройте приложение для прослушивания порта 8080. Это общее соглашение для пользователей, не являющихся пользователями.

  • Инкапсулировать зависимости. Убедитесь, что все зависимости для функции приложения инкапсулируются в образе контейнера Docker. Инкапсуляция позволяет приложению надежно развертываться в широком диапазоне узлов.

  • Выберите правильные базовые изображения. Выбранный базовый образ зависит от среды развертывания. Если вы развертываете в контейнерных приложениях, например, необходимо использовать образы Docker для Linux.

Эталонная реализация демонстрирует процесс сборки Docker для контейнеризации приложения Java. Этот Файл Dockerfile использует одноэтапную сборку с базовым образом OpenJDK,mcr.microsoft.com/openjdk/jdk:17-ubuntu который предоставляет необходимую среду выполнения Java.

Dockerfile включает следующие действия.

  1. Объявление тома: определяется временный том (/tmp) и позволяет временное хранилище файлов отдельно от основной файловой системы контейнера.
  2. Копирование артефактов: JAR-файл приложения копируетсяemail-processor.jar в контейнер вместе с агентом Application Insights (applicationinsights-agent.jar) для мониторинга.
  3. Установка точки входа: контейнер настроен для запуска приложения с включенным агентом Application Insights, используя java -javaagent для мониторинга приложения во время выполнения.

Этот файл Dockerfile позволяет использовать образ только в том числе зависимости среды выполнения, подходящие для сред развертывания, таких как приложения контейнеров, которые поддерживают контейнеры на основе Linux.

# Use OpenJDK 17 base image on Ubuntu as the foundation
FROM mcr.microsoft.com/openjdk/jdk:17-ubuntu

# Define a volume to allow temporary files to be stored separately from the container's main file system
VOLUME /tmp

# Copy the packaged JAR file into the container
COPY target/email-processor.jar app.jar

# Copy the Application Insights agent for monitoring
COPY target/agent/applicationinsights-agent.jar applicationinsights-agent.jar

# Set the entry point to run the application with the Application Insights agent
ENTRYPOINT ["java", "-javaagent:applicationinsights-agent.jar", "-jar", "/app.jar"]

Развертывание эталонной реализации

Разверните эталонную реализацию шаблона современного веб-приложения для Java. В репозитории приведены инструкции по разработке и рабочему развертыванию. После развертывания можно имитировать и наблюдать за шаблонами проектирования.

Схема, показывающая архитектуру эталонной реализации.Рис. 3. Архитектура эталонной реализации. Скачайте файл Visio этой архитектуры.