Поделиться через


Рекомендации по проектированию приложений для критически важных рабочих нагрузок

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

Внимание

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

Структура приложения

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

Приложение использует конечные точки API без отслеживания состояния, которые отделяют длительные запросы на запись асинхронно через брокер обмена сообщениями. Композиция рабочей нагрузки позволяет удалять и создавать все кластеры Служба Azure Kubernetes (AKS) и другие зависимости в метке в любое время. Основными компонентами приложения являются:

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

  • API (CatalogService): REST API, который вызывается приложением пользовательского интерфейса, но по-прежнему доступен для других потенциальных клиентских приложений.

  • Рабочая роль (BackgroundProcessor): фоновая рабочая роль, которая прослушивает новые события в шине сообщений и обрабатывает запросы на запись в базу данных. Этот компонент не предоставляет интерфейсы API.

  • API службы работоспособности (HealthService): API, который сообщает о работоспособности приложения, проверяя, работают ли критически важные компоненты, такие как база данных или шина обмена сообщениями.

    Схема, показывющая поток приложения.

Рабочая нагрузка состоит из приложений API, рабочей роли и проверки работоспособности. Выделенное пространство имен AKS, называемое workload размещением рабочей нагрузки в качестве контейнеров. Прямой обмен данными между модулями pod не выполняется. Модули pod являются бессерверными и могут масштабироваться независимо.

Схема, показывающая подробную композицию рабочей нагрузки.

К другим вспомогательным компонентам, которые выполняются в кластере, относятся:

  • Контроллер входящего трафика NGINX: направляет входящие запросы в рабочую нагрузку и балансирует нагрузку между модулями pod. Контроллер входящего трафика NGINX предоставляется через Azure Load Balancer с общедоступным IP-адресом, но доступ к ним можно получить только через Azure Front Door.

  • Диспетчер сертификатов: автопроигрыватель Jetstack cert-manager использует сертификаты tls, используя давайте зашифруем для правил входящего трафика.

  • Драйвер CSI хранилища секретов: поставщик Azure Key Vault для драйвера CSI хранилища секретов безопасно считывает секреты, такие как строка подключения из Key Vault.

  • Агент мониторинга. Конфигурация OMSAgentForLinux по умолчанию корректируется, чтобы уменьшить объем данных мониторинга, отправленных в рабочую область журналов Azure Monitor.

Подключение к базе данных

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

В эталонной реализации Azure Cosmos DB служит основным хранилищем данных для приложения. Azure Cosmos DB предоставляет записи в нескольких регионах. Каждая метка может записываться в реплику Azure Cosmos DB в одном регионе, а Azure Cosmos DB внутренне обрабатывает репликацию данных и синхронизацию между регионами. Azure Cosmos DB для NoSQL поддерживает все возможности ядра СУБД.

Дополнительные сведения см. в разделе "Платформа данных" для критически важных рабочих нагрузок.

Примечание.

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

Для критически важных приложений, которые определяют доступность по сравнению с производительностью, рекомендуется выполнять запись в одном регионе и чтение с несколькими регионами с высоким уровнем согласованности .

Эта архитектура использует хранилище для временного хранения состояния в метке для Центры событий Azure контрольных точек.

Все компоненты рабочей нагрузки используют пакет SDK для .NET Core для Azure Cosmos DB для взаимодействия с базой данных. Пакет SDK включает надежную логику для поддержания подключения к базе данных и обработки сбоев. К ключевым параметрам конфигурации относятся:

  • Режим прямого подключения. Этот параметр используется по умолчанию для пакета SDK для .NET версии 3, так как он обеспечивает более высокую производительность. Режим прямого подключения имеет меньше сетевых прыжков по сравнению с режимом шлюза, который использует ПРОТОКОЛ HTTP.

  • Возврат ответа на запись содержимого: этот подход отключен, чтобы клиент Azure Cosmos DB не смог вернуть документ из создания, upsert и исправлений и замены операций, что снижает сетевой трафик. Дальнейшая обработка на клиенте не требует этого параметра.

  • Настраиваемая сериализация: этот процесс задает политику именования свойств JSON, чтобы JsonNamingPolicy.CamelCase преобразовать свойства .NET в стандартные свойства JSON. Он также может переводить свойства JSON в свойства .NET. Условие по умолчанию игнорирует свойства со значениями NULL, например JsonIgnoreCondition.WhenWritingNullво время сериализации.

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

Следующий блок кода отображается в эталонной реализации:

//
// /src/app/AlwaysOn.Shared/Services/CosmosDbService.cs
//
CosmosClientBuilder clientBuilder = new CosmosClientBuilder(sysConfig.CosmosEndpointUri, sysConfig.CosmosApiKey)
    .WithConnectionModeDirect()
    .WithContentResponseOnWrite(false)
    .WithRequestTimeout(TimeSpan.FromSeconds(sysConfig.ComsosRequestTimeoutSeconds))
    .WithThrottlingRetryOptions(TimeSpan.FromSeconds(sysConfig.ComsosRetryWaitSeconds), sysConfig.ComsosMaxRetryCount)
    .WithCustomSerializer(new CosmosNetSerializer(Globals.JsonSerializerOptions));

if (sysConfig.AzureRegion != "unknown")
{
    clientBuilder = clientBuilder.WithApplicationRegion(sysConfig.AzureRegion);
}

_dbClient = clientBuilder.Build();

Асинхронное обмен сообщениями

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

Ключевыми характеристиками асинхронного обмена сообщениями являются:

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

  • Службы масштабируется независимо.

  • Сбои нижестоящего потока не влияют на клиентские транзакции.

  • Целостность транзакций трудно поддерживать, так как создание и сохраняемость данных происходят в отдельных службах. Целостность транзакций — это проблема в службах обмена сообщениями и сохраняемости. Дополнительные сведения см. в разделе "Идемпотентная обработка сообщений".

  • Для комплексной трассировки требуется сложная оркестрация.

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

Центры событий брокеры сообщений между API и рабочей ролью.

Внимание

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

Запись сведений о реализации операций

Операции записи, такие как post rating и post comment, обрабатываются асинхронно. API сначала отправляет сообщение со всеми соответствующими сведениями, такими как тип действия и данные комментариев, в очередь сообщений и немедленно возвращается HTTP 202 (Accepted) с Location заголовком создаваемого объекта.

BackgroundProcessor экземпляры обрабатывают сообщения в очереди и обрабатывают фактическую связь базы данных для операций записи. BackgroundProcessor масштабируется и масштабируется динамически на основе тома сообщения очереди. Ограничение масштабирования экземпляров процессора определяется максимальным числом секций Центров событий, которое составляет 32 для уровней "Базовый" и "Стандартный", 100 для уровня "Премиум" и 1024 для уровня "Выделенный".

Схема, показывающая асинхронную природу функции оценки после оценки в реализации.

Библиотека BackgroundProcessor обработчика Центры событий Azure использует Хранилище BLOB-объектов Azure для управления владением секциями, балансировки нагрузки между разными экземплярами рабочих ролей и использования контрольных точек для отслеживания хода выполнения. Контрольные точки не записываются в хранилище BLOB-объектов после каждого события, так как она добавляет дорогостоящую задержку для каждого сообщения. Вместо этого контрольные точки записываются в цикл таймера и можно настроить длительность. Значение по умолчанию — 10 секунд.

Следующий блок кода отображается в эталонной реализации:

while (!stoppingToken.IsCancellationRequested)
{
    await Task.Delay(TimeSpan.FromSeconds(_sysConfig.BackendCheckpointLoopSeconds), stoppingToken);
    if (!stoppingToken.IsCancellationRequested && !checkpointEvents.IsEmpty)
    {
        string lastPartition = null;
        try
        {
            foreach (var partition in checkpointEvents.Keys)
            {
                lastPartition = partition;
                if (checkpointEvents.TryRemove(partition, out ProcessEventArgs lastProcessEventArgs))
                {
                    if (lastProcessEventArgs.HasEvent)
                    {
                        _logger.LogDebug("Scheduled checkpointing for partition {partition}. Offset={offset}", partition, lastProcessEventArgs.Data.Offset);
                        await lastProcessEventArgs.UpdateCheckpointAsync();
                    }
                }
            }
        }
        catch (Exception e)
        {
            _logger.LogError(e, "Exception during checkpointing loop for partition={lastPartition}", lastPartition);
        }
    }
}

Если приложение обработчика столкнулось с ошибкой или остановлено, прежде чем оно сможет обработать сообщение:

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

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

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

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

API напрямую обрабатывает операции чтения и немедленно возвращает данные пользователю.

Схема, показывающая процесс операций чтения.

Метод обратного канала не установлен для обмена данными с клиентом, если операция завершится успешно. Клиентское приложение должно заранее опрашивить API для обновления элемента, указанного в заголовке Location HTTP.

Масштабируемость

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

Реализация упаковывала службы в виде образов контейнеров и использует диаграммы Helm для развертывания служб на каждой метках. Службы настроены для ожидаемых запросов и ограничений Kubernetes и предварительно настроенных правил автоматического масштабирования. BackgroundProcessor Компоненты CatalogService рабочей нагрузки могут масштабироваться и масштабироваться по отдельности, так как обе службы являются бессерверными.

Пользователи взаимодействуют непосредственно с CatalogServiceрабочей нагрузкой, поэтому эта часть рабочей нагрузки должна отвечать под любой нагрузкой. Существует не менее трех экземпляров для каждого кластера для распределения по трем зонам доступности в регионе Azure. Горизонтальное автомасштабирование pod (HPA) в AKS автоматически добавляет больше модулей pod по мере необходимости. Функция автомасштабирования Azure Cosmos DB может динамически увеличивать и уменьшать единицы запросов (ЕЗ), доступные для коллекции. Azure CatalogService Cosmos DB объединяются для формирования единицы масштабирования в метку.

HPA развертывается с диаграммой Helm с настраиваемым максимальным числом и минимальным количеством реплик. Нагрузочный тест определил, что каждый экземпляр может обрабатывать около 250 запросов в секунду со стандартным шаблоном использования.

Служба BackgroundProcessor имеет различные требования и считается фоновой рабочей ролью, которая оказывает ограниченное влияние на взаимодействие с пользователем. Поэтому BackgroundProcessor имеет другую конфигурацию автоматического масштабирования по сравнению с CatalogService, и она может масштабироваться в диапазоне от 2 до 32 экземпляров. Определите это ограничение на основе количества секций, используемых в центрах событий. Вам не требуется больше рабочих ролей, чем секции.

Компонент minReplicas maxReplicas
CatalogService 3 20
BackgroundProcessor 2 32

Каждый компонент рабочей нагрузки, включающей зависимости, например ingress-nginx , имеет параметр "Бюджеты нарушений pod" (PDBS), настроенный для обеспечения доступности минимального количества экземпляров при изменении кластеров.

Следующий блок кода отображается в эталонной реализации:

#
# /src/app/charts/healthservice/templates/pdb.yaml
# Example pod distribution budget configuration.
#
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: {{ .Chart.Name }}-pdb
spec:
  minAvailable: 1
  selector:
    matchLabels:
      app: {{ .Chart.Name }}

Примечание.

Определите фактическое минимальное число и максимальное количество модулей pod для каждого компонента с помощью нагрузочного тестирования. Количество модулей pod может отличаться для каждой рабочей нагрузки.

Инструментирование

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

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

Эта архитектура реализует распределенную трассировку с помощью Application Insights и рабочей области журналов Azure Monitor для данных мониторинга приложений. Используйте журналы Azure Monitor для журналов и метрик рабочих нагрузок и компонентов инфраструктуры. Эта архитектура реализует полную сквозную трассировку запросов, поступающих из API, через Центры событий, а затем в Azure Cosmos DB.

Внимание

Развертывание ресурсов мониторинга меток в отдельной группе ресурсов мониторинга. Ресурсы имеют другой жизненный цикл, отличный от самого метки. Дополнительные сведения см. в разделе "Мониторинг данных для ресурсов меток".

Схема отдельных глобальных служб, служб мониторинга и развертывания меток.

Сведения о реализации мониторинга приложений

Компонент BackgroundProcessor использует Microsoft.ApplicationInsights.WorkerService пакет NuGet для получения встроенных инструментирования из приложения. Serilog также используется для всех журналов внутри приложения. Application Insights настраивается в качестве приемника в дополнение к приемнику консоли. TelemetryClient Экземпляр Application Insights используется непосредственно, только если необходимо отслеживать другие метрики.

Следующий блок кода отображается в эталонной реализации:

//
// /src/app/AlwaysOn.BackgroundProcessor/Program.cs
//
public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
    .ConfigureServices((hostContext, services) =>
    {
        Log.Logger = new LoggerConfiguration()
                            .ReadFrom.Configuration(hostContext.Configuration)
                            .Enrich.FromLogContext()
                            .WriteTo.Console(outputTemplate: "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} {Level:u3}] {Message:lj} {Properties:j}{NewLine}{Exception}")
                            .WriteTo.ApplicationInsights(hostContext.Configuration[SysConfiguration.ApplicationInsightsConnStringKeyName], TelemetryConverter.Traces)
                            .CreateLogger();
    }

Снимок экрана: сквозная возможность трассировки.

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

Следующий блок кода отображается в эталонной реализации:

//
// /src/app/AlwaysOn.CatalogService/Startup.cs
//
app.Use(async (context, next) =>
{
    context.Response.OnStarting(o =>
    {
        if (o is HttpContext ctx)
        {
            // ... code omitted for brevity
            context.Response.Headers.Add("Server-Location", sysConfig.AzureRegion);
            context.Response.Headers.Add("Correlation-ID", Activity.Current?.RootId);
            context.Response.Headers.Add("Requested-Api-Version", ctx.GetRequestedApiVersion()?.ToString());
        }
        return Task.CompletedTask;
    }, context);
    await next();
});

Примечание.

Адаптивная выборка включена по умолчанию в пакете SDK Application Insights. Адаптивная выборка означает, что не каждый запрос отправляется в облако и доступен для поиска по идентификатору. Команды приложений, критически важные для миссии, должны надежно отслеживать каждый запрос, поэтому эталонная реализация отключила адаптивную выборку в рабочей среде.

Сведения о реализации мониторинга Kubernetes

Параметры диагностики можно использовать для отправки журналов и метрик AKS в журналы Azure Monitor. Вы также можете использовать функцию аналитики контейнеров с AKS. Включите аналитику контейнеров для развертывания OMSAgentForLinux с помощью DaemonSet Kubernetes на каждом узле в кластерах AKS. OMSAgentForLinux может собирать больше журналов и метрик из кластера Kubernetes и отправлять их в соответствующую рабочую область журналов Azure Monitor. Эта рабочая область содержит подробные данные о модулях pod, развертываниях, службах и общей работоспособности кластера.

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

Следующий блок кода отображается в эталонной реализации:

#
# /src/config/monitoring/container-azm-ms-agentconfig.yaml
# This is just a snippet showing the relevant part.
#
[log_collection_settings]
    [log_collection_settings.stdout]
        enabled = false

        exclude_namespaces = ["kube-system"]

Дополнительные сведения см. в полном файле конфигурации.

Мониторинг работоспособности приложений

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

Эта архитектура применяет мониторинг работоспособности на следующих уровнях:

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

  • служба работоспособности, который является выделенным компонентом в кластере. Azure Front Door настроен для проверки служба работоспособности в каждой метке и удаления неработоспособных меток из автоматической балансировки нагрузки.

сведения о реализации служба работоспособности

HealthService — это компонент рабочей нагрузки, который выполняется вместе с другими компонентами, такими как CatalogService и BackgroundProcessorв вычислительном кластере. HealthService предоставляет REST API, который вызывает проверку работоспособности Azure Front Door для определения доступности метки. В отличие от основных проб активности, служба работоспособности является более сложным компонентом, который предоставляет состояние зависимостей в дополнение к собственному состоянию.

Схема службы работоспособности, запрашивающей Azure Cosmos DB, Центры событий и хранилище.

служба работоспособности не отвечает, если кластер AKS отключен, что отрисовывает неработоспособную рабочую нагрузку. При запуске службы он выполняет периодические проверки критически важных компонентов решения. Все проверки выполняются асинхронно и параллельно. Если какая-либо из проверок завершается ошибкой, весь сметок недоступен.

Предупреждение

Пробы работоспособности Azure Front Door могут наложить значительную нагрузку на служба работоспособности, так как запросы приходят из нескольких точек присутствия (PoP). Чтобы предотвратить перегрузку подчиненных компонентов, реализуйте эффективное кэширование.

служба работоспособности также используется для явно настроенных тестов ping URL-адресов с ресурсом Application Insights каждой метки.

Дополнительные сведения о реализации см. в HealthService разделе "Приложение служба работоспособности".

Следующий шаг