Была ли эта страница полезной?
Ваш отзыв об этом контенте важен для нас. Расскажите нам о том, что вы думаете.
Дополнительный отзыв?
1500 символов осталось
Экспорт (0) Печать
Развернуть все
Развернуть Свернуть

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

Обновлено: Июнь 2015 г.

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

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

В этом разделе объясняются разные аспекты, используемые Служебная шина для повышения производительности.

Служебная шина позволяет клиентам отправлять и получать сообщения по двум протоколам: клиентскому протоколу Служебная шина и HTTP. Клиентский протокол Служебная шина является более эффективным, поскольку он поддерживает подключение к службе Служебная шина, если существует фабрика сообщений. Он также реализует пакетную обработку и предварительную выборку. Клиентский протокол Служебная шина доступен для приложений .NET, использующих управляемый .NET API.

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

Клиентские объекты Служебная шина, такие как Microsoft.ServiceBus.Messaging.QueueClient или Microsoft.ServiceBus.Messaging.MessageSender, создаются с помощью объекта MessagingFactory, который также предоставляет внутреннее управление подключениями. Вам не следует закрывать фабрики обмена сообщениями или клиенты очередей, разделов и подписок после отправки сообщения, а затем создавать их снова при отправке следующего сообщения. При закрытии фабрики обмена сообщениями удаляется подключение к службе Служебная шина, а новое подключение устанавливается при повторном создании фабрики. Установка подключения является ресурсоемкой операцией, которой можно избежать, если повторно использовать ту же фабрику и клиентские объекты в нескольких операциях.

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

  • Асинхронные операции: клиент объединяет операции в конвейер, выполняя асинхронные операции. Следующий запрос запускается перед завершением предыдущего запроса. Ниже приведен пример асинхронной операции отправки:

    BrokeredMessage m1 = new BrokeredMessage(body);
    BrokeredMessage m2 = new BrokeredMessage(body);
    
    Task send1 = queueClient.SendAsync(m1).ContinueWith((t) => 
      {
        Console.WriteLine("Sent message #1");
      });
    Task send2 = queueClient.SendAsync(m2).ContinueWith((t) => 
      {
        Console.WriteLine("Sent message #2");
      });
    Task.WaitAll(send1, send2);
    Console.WriteLine("All messages sent");
    
    
    
    
    
    
    
    
    
    
    
    Ниже приведен пример асинхронной операции получения.

    Task receive1 = queueClient.ReceiveAsync().ContinueWith(ProcessReceivedMessage);
    Task receive2 = queueClient.ReceiveAsync().ContinueWith(ProcessReceivedMessage);
    
    Task.WaitAll(receive1, receive2);
    Console.WriteLine("All messages received");
    
    async void ProcessReceivedMessage(Task<BrokeredMessage> t)
    {
      BrokeredMessage m = t.Result;
      Console.WriteLine("{0} received", m.Label);
      await m.CompleteAsync();
      Console.WriteLine("{0} complete", m.Label);
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
  • Несколько фабрик: все клиенты (отправители и получатели), созданные одной фабрикой, совместно используют одно TCP-соединение. Максимальная пропускная способность сообщений ограничена числом операций, которые могут проходить через это TCP-соединение. Пропускная способность, которую можно получить в одной фабрике, существенно зависит от времени приема-передачи TCP и размера сообщения. Чтобы получить более высокую пропускную способность, следует использовать несколько фабрик обмена сообщениями.

При создании клиента очереди или подписки можно указать режим получения Блокировка при просмотре или Получение и удаление. Режим получения по умолчанию — PeekLock. При работе в этом режиме клиент отправляет запрос на получение сообщения из Служебная шина. После получения сообщения клиент отправляет запрос на завершение сообщения.

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

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

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

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

Чтобы отключить использование пакетов, установите для свойства BatchFlushInterval значение TimeSpan.Zero. Например:

MessagingFactorySettings mfs = new MessagingFactorySettings();
mfs.TokenProvider = tokenProvider;
mfs.NetMessagingTransportSettings.BatchFlushInterval = TimeSpan.FromSeconds(0.05);
MessagingFactory messagingFactory = MessagingFactory.Create(namespaceUri, mfs);

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

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

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

QueueDescription qd = new QueueDescription();
qd.EnableBatchedOperations = false;
Queue q = namespaceManager.CreateQueue(qd);

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

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

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

При использовании срока блокировки по умолчанию в 60 секунд для Microsoft.ServiceBus.Messaging.SubscriptionClient.PrefetchCount хорошо подходит значение, в 20 раз превышающее максимальную скорость обработки для всех получателей фабрики. Например, фабрика создает 3 получателя, и каждый получатель может обработать до 10 сообщений в секунду. Счетчик предварительной выборки не должен превышать 20 * 3 * 10 = 600. По умолчанию Microsoft.ServiceBus.Messaging.QueueClient.PrefetchCount имеет значение 0, означающее, что из службы не извлечено никаких дополнительных сообщений.

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

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

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

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

TopicDescription td = new TopicDescription(TopicName);
td.EnableExpress = true;
namespaceManager.CreateTopic(td);

Если в экспресс-сущность отправляется сообщение, содержащее критически важные сведения, которые не должны быть потеряны, отправитель может потребовать от Служебная шина немедленно сохранить это сообщение в постоянном хранилище, задав для свойства ForcePersistence значение true. Дополнительную информацию см. в разделе Новые возможности выпуска 2.3 Azure SDK (апрель 2014).

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

// Create partitioned queue.
QueueDescription qd = new QueueDescription(QueueName);
qd.EnablePartitioning = true;
namespaceManager.CreateQueue(qd);

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

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

Задача: максимально увеличить пропускную способность одной очереди. Число отправителей и получателей мало.

  • Используйте секционированную очередь для повышения производительности и доступности.

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

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

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

  • Установите пакетный интервал в 50 мс, чтобы уменьшить число передач клиентского протокола Служебная шина. Если используется несколько отправителей, увеличьте интервал пакетов до 100 мс.

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

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

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

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

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

  • Используйте секционированную очередь для повышения уровня доступности.

  • Отключите пакетную обработку на стороне клиента. Клиент немедленно отправляет сообщение.

  • Отключите доступ к хранилищу в пакетном режиме. Служба немедленно записывает сообщение в хранилище.

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

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

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

Служебная шина включает до 1 000 одновременных подключений к сущности обмена сообщениями (или 5 000 при использовании AMQP). Это ограничение действует на уровне пространства имен. Для очередей, разделов и подписок устанавливается ограничение на количество параллельных соединений для каждого пространства имен. В очередях это количество является общим для отправителей и получателей. Если отправителям требуются все 1 000 подключений, следует заменить очередь разделом и одной подпиской. Раздел принимает до 1 000 параллельных подключений от отправителей, а подписка принимает дополнительно 1 000 параллельных подключений от получателей. Если требуется более 1 000 параллельных отправителей, то отправители должны отправлять сообщения в протокол Служебная шина через HTTP.

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

  • Используйте секционированную очередь для повышения производительности и доступности.

  • Если каждый отправитель размещен в другом процессе, используйте только одну фабрику на процесс.

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

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

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

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

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

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

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

  • Используйте секционированную очередь для повышения производительности и доступности.

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

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

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

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

Задача: максимально увеличить пропускную способность раздела с небольшим числом подписок. Сообщение получается большим числом подписок. Это означает, что объединенная скорость получения по всем подпискам больше, чем скорость отправки. Число отправителей невелико. Число получателей в каждой подписке невелико.

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

  • Используйте секционированный раздел для повышения производительности и доступности.

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

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

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

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

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

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

Задача: максимально увеличить пропускную способность раздела с большим числом подписок. Сообщение получается большим числом подписок. Это означает, что объединенная скорость получения по всем подпискам гораздо больше, чем скорость отправки. Число отправителей невелико. Число получателей в каждой подписке невелико.

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

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

  • Используйте секционированный раздел для повышения производительности и доступности.

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

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

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

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

Показ:
© 2015 Microsoft