Прочитать на английском

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


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

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

В этой статье термин "клиент" означает любую сущность, которая имеет доступ к шине данных. Клиент может быть как отправителем, так и получателем. Термин "отправитель" используется для обозначения клиента очереди Service Bus или клиента темы, который отправляет сообщения в очередь Service Bus или тему. Термин "получатель" используется в отношении клиента очереди или подписки служебной шины, который получает сообщения из очереди служебной шины или подписки.

Планирование ресурсов и рекомендации

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

Ценовая категория

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

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

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

Примечание

Если выбран неправильный уровень, существует риск перегрузки пространства имен служебной шины, что может привести к ограничению.

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

Расчет пропускной способности для категории "Премиум"

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

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

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

Бенчмарки

Ниже приведен пример GitHub , который можно запустить, чтобы увидеть ожидаемую пропускную способность, полученную для пространства имен служебной шины. В наших эталонных тестах мы наблюдали скорость примерно 4 МБ/секунду на единицу обмена сообщениями (MU) для входящего и исходящего трафика.

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

Рекомендации по вычислениям

Служебная шина запускает несколько фоновых процессов, которые могут повлиять на использование вычислительных ресурсов. К ним относятся, но не ограничиваются таймерами, расписаниями и передачей метрик. Кроме того, использование некоторых функций Service Bus требует вычислительных ресурсов, что может снизить ожидаемую пропускную способность. Вот некоторые из этих функций:

  1. Сеансы.
  2. Распространение на несколько подписок по одной теме.
  3. Запуск множества фильтров в одной подписке.
  4. Запланированные сообщения.
  5. Отложенные сообщения.
  6. Транзакции.
  7. Дедупликация и временное окно обратного просмотра.
  8. Пересылка (перенаправление от одной сущности к другой).

Если в вашем приложении используется любая из перечисленных выше функций и вы не получаете ожидаемой пропускной способности, вы можете просмотреть метрики использования ЦП и рассмотреть возможность масштабирования пространства имен премиум-служебной шины. Вы также можете использовать Azure Monitor для автоматического масштабирования пространства имен служебной шины. Рекомендуется увеличить количество единиц сообщений ,когда использование ЦП превышает 70%, чтобы обеспечить оптимальную производительность.

Шардинг в пространствах имен

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

В этом случае более оптимальным вариантом будет сегментировать сущности (очереди и разделы) в разных пространствах имен Служебной шины категории "Премиум". Можно также рассмотреть сегментирование между разными пространствами имен в разных регионах Azure.

Протоколы

Служебная шина позволяет клиентам отправлять и получать сообщения с помощью трех протоколов.

  1. Расширенный протокол управления очередью сообщений (AMQP)
  2. Протокол обмена сообщениями шины обслуживания (SBMP)
  3. Протокол HTTP

Протокол AMQP является наиболее эффективным, так как поддерживает подключение к служебной шине. Он также реализует пакетную обработку и предварительную выборку. Если явно не указано иное, в этой статье предполагается использование протокола AMQP или SBMP.

Важно!

Протокол SBMP доступен только для платформы .NET Framework. AMQP используется по умолчанию для .NET Standard.

30 сентября 2026 года мы прекратим поддержку протокола SBMP для Azure Service Bus, и вы больше не сможете использовать этот протокол после этой даты. Выполните миграцию на библиотеки SDK последней версии для Служебной шины Azure с использованием протокола AMQP, который предоставляет критически важные обновления безопасности и улучшенные возможности, до указанного срока.

Дополнительные сведения см. в объявлении о прекращении поддержки.

Выбор соответствующего пакета SDK для служебной шины .NET

Пакет Azure.Messaging.ServiceBus — это последний пакет SDK Служебной шины Azure для .NET, доступный по состоянию на ноябрь 2020 г. Существует два старых пакета SDK для .NET, которые будут продолжать получать критические исправления ошибок до 30 сентября 2026 года, но мы настоятельно рекомендуем использовать последний пакет SDK. Дополнительные сведения о переходе из старых пакетов SDK см. в руководстве по миграции .

Пакет NuGet Основные пространства имен Минимальные платформы Протоколы
Azure.Messaging.ServiceBus (последняя версия) Azure.Messaging.ServiceBus
Azure.Messaging.ServiceBus.Administration
.NET Core 2.0;
.NET Framework 4.6.1
Mono 5.4
универсальная платформа Windows 10.0.16299.
AMQP
HTTP
Microsoft.Azure.ServiceBus Microsoft.Azure.ServiceBus
Microsoft.Azure.ServiceBus.Management
.NET Core 2.0;
.NET Framework 4.6.1
Mono 5.4
универсальная платформа Windows 10.0.16299.
AMQP
HTTP

Дополнительные сведения о минимальной поддержке платформы .NET Standard см. в разделе о поддержке реализации .NET.

30 сентября 2026 г. мы прекратим поддержку библиотек пакета SDK Служебная шина Azure WindowsAzure.ServiceBus, Microsoft.Azure.ServiceBus и com.microsoft.azure.servicebus, которые не соответствуют руководящим принципам SDK Azure. Мы также завершим поддержку протокола SBMP, поэтому вы больше не сможете использовать этот протокол после 30 сентября 2026 года. Перейдите в последние библиотеки пакета SDK Azure, которые предлагают критически важные обновления системы безопасности и улучшенные возможности до этой даты.

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

Повторное использование фабрик и клиентов

Клиенты служебной шины, взаимодействующие со службой, такие как ServiceBusClient, ServiceBusSender, ServiceBusReceiver и ServiceBusProcessor, должны быть зарегистрированы для внедрения зависимостей как одиночные экземпляры (или создайте экземпляр один раз и используйте совместно). ServiceBusClient (фабрика) можно зарегистрировать для внедрения зависимостей с помощью ServiceBusClientBuilderExtensions.

Рекомендуется не закрывать или удалять эти клиенты после отправки или получения каждого сообщения. Закрытие или удаление объектов, зависящих от сущности (ServiceBusSender/Receiver/Processor), приводит к разрыву соединения с службой Service Bus. Удаление ServiceBusClient приведет к разрыву соединения с сервисом Service Bus.

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

Следующее примечание относится ко всем пакетам SDK:

Примечание

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

Параллельные операции

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

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

var messageOne = new ServiceBusMessage(body);
var messageTwo = new ServiceBusMessage(body);

var sendFirstMessageTask =
    sender.SendMessageAsync(messageOne).ContinueWith(_ =>
    {
        Console.WriteLine("Sent message #1");
    });
var sendSecondMessageTask =
    sender.SendMessageAsync(messageTwo).ContinueWith(_ =>
    {
        Console.WriteLine("Sent message #2");
    });

await Task.WhenAll(sendFirstMessageTask, sendSecondMessageTask);
Console.WriteLine("All messages sent");

Следующий код является примером асинхронной операции приёма.

var client = new ServiceBusClient(connectionString);
var options = new ServiceBusProcessorOptions 
{

      AutoCompleteMessages = false,
      MaxConcurrentCalls = 20
};
await using ServiceBusProcessor processor = client.CreateProcessor(queueName,options);
processor.ProcessMessageAsync += MessageHandler;
processor.ProcessErrorAsync += ErrorHandler;

static Task ErrorHandler(ProcessErrorEventArgs args)
{
    Console.WriteLine(args.Exception);
    return Task.CompletedTask;
};

static async Task MessageHandler(ProcessMessageEventArgs args)
{
    Console.WriteLine("Handle message");
    await args.CompleteMessageAsync(args.Message);
}

await processor.StartProcessingAsync();

Режим получения

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

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

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

Предварительная загрузка

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

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

При использовании срока действия блокировки по умолчанию в 60 секунд хорошее значение для PrefetchCount составляет 20-кратное максимальное значение скорости обработки всех получателей фабрики. Например, фабрика создает трех получателей, каждый из которых может обработать до 10 сообщений в секунду. Количество объектов предварительной выборки не должно превышать 20 × 3 × 10 = 600. По умолчанию PrefetchCount установлено на 0, что означает, что дополнительные сообщения не извлекаются из службы.

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

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

Предварительная выборка не влияет на количество оплачиваемых операций обмена сообщениями и доступна только для протокола клиента Service Bus. Протокол HTTP не поддерживает предварительную выборку. Предварительная выборка доступна как для синхронных, так и для асинхронных операций получения.

Дополнительные сведения см. в следующих свойствах PrefetchCount:

Эти свойства можно задать в ServiceBusReceiverOptions или ServiceBusProcessorOptions.

Предварительная загрузка и ReceiveMessagesAsync

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

Предварительная выборка — это конфигурация (или режим) в ServiceBusReceiver, а ReceiveMessagesAsync является операцией (которая имеет семантику ответа на запрос).

При совместном использовании этих подходов рассмотрим следующие случаи.

  • Буферизация сообщений должна быть больше или равна количеству сообщений, которые ожидается получить от ReceiveMessagesAsync.
  • Предвыборка может достигать n/3 раз от числа сообщений, обрабатываемых в секунду, где n — это продолжительность блокировки по умолчанию.

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

Несколько очередей или тем

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

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

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

Секционированные пространства имен

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

Сценарии

В следующих разделах описываются типичные сценарии обмена сообщениями и приводятся рекомендации по настройкам Service Bus. Пропускная способность бывает небольшой (менее 1 сообщения в секунду), средней (1 сообщение в секунду или больше, но не более 100 сообщений в секунду) и высокой (100 сообщений в секунду или больше). Число клиентов классифицируется как небольшое (5 или меньше), умеренный (более 5, но меньше или равно 20) и большой (более 20).

Очередь с высокой пропускной способностью

Цель: максимально повысить пропускную способность одной очереди. Количество отправителей и получателей: небольшое.

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

Несколько очередей с высокой пропускной способностью

Цель: максимально повысить общую пропускную способность нескольких очередей. Пропускная способность одной очереди: средняя или высокая.

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

Очередь с низкой задержкой

Цель: минимизировать время задержки в очереди или разделе. Количество отправителей и получателей: небольшое. Пропускная способность очереди: низкая или средняя.

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

Очередь с большим числом отправителей

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

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

Чтобы повысить пропускную способность, выполните следующие действия.

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

Очередь с большим числом получателей

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

Service Bus позволяет до 1000 одновременных подключений к сущности. Если для очереди требуется более 1000 получателей, замените очередь темой и несколькими подписками. Каждая подписка может поддерживать до 1000 одновременных подключений. Кроме того, получатели могут обращаться к очереди через протокол HTTP.

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

  • Если каждый получатель размещается в отдельном процессе, используйте только одну фабрику для каждого процесса.
  • Для количества элементов предварительной выборки установите небольшое значение (например, PrefetchCount = 10). Это позволит избежать ситуации, когда одни получатели простаивают, а другие получают множество кэшированных сообщений.

Раздел с несколькими подписками

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

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

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

Раздел с большим количеством подписок

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

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

Чтобы максимально повысить пропускную способность, попробуйте выполнить следующие шаги:

  • Установите значение предварительной выборки равным 20-кратному ожидаемой частоты получения сообщений. Это снизит число передач по протоколу клиента служебной шины.

Дополнительные ресурсы