Пакетная обработка сообщений в транзакции

Приложения в очереди используют транзакции для обеспечения правильности и надежной доставки сообщений. Однако транзакции являются дорогостоящими операциями и могут значительно снизить пропускную способность сообщений. Одним из способов повышения пропускной способности сообщений является чтение и обработка нескольких сообщений в одной транзакции. Компромисс заключается между производительностью и восстановлением: с увеличением количества сообщений в пакете увеличивается и объем работ по восстановлению, который требуется в случае отката транзакций. Важно отметить разницу между пакетным сообщением в транзакции и сеансах. Сеанс — это группировка связанных сообщений, обрабатываемых одним приложением и зафиксированных в виде одной единицы. Сеансы обычно используются, когда необходимо обработать группу связанных сообщений. Примером этого является веб-сайт интернет-покупок. Пакеты используются для обработки нескольких несвязанных сообщений таким образом, чтобы увеличить пропускную способность сообщения. Дополнительные сведения о сеансах см. в разделе "Группирование сообщений в очереди" в сеансе. Сообщения в пакете также обрабатываются одним приложением и фиксируются в виде одной единицы, но между сообщениями в пакете не может быть связи. Пакетная обработка сообщений в транзакции — это оптимизация, которая не изменяет способ работы приложения.

Ввод режима пакетной обработки

Поведение конечной TransactedBatchingBehavior точки управляет пакетной обработкой. Добавление этого поведения конечной точки в конечную точку службы сообщает Windows Communication Foundation (WCF) формировать сообщения в пакет в рамках транзакции. Не все сообщения требуют транзакции, поэтому только сообщения, требующие транзакции, помещаются в пакет, и только сообщения, отправленные из операций, помеченных TransactionScopeRequired = true и TransactionAutoComplete = true считаются для пакета. Если все операции с контрактом службы отмечены TransactionScopeRequired = false и TransactionAutoComplete = false, то режим пакетной обработки никогда не активируется.

Фиксация транзакции

Пакетная транзакция фиксируется на основе следующего:

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

  • Transaction Timeout. После того, как истечет 80 процентов времени ожидания транзакции, пакет фиксируется и создается новый пакет. Это означает, что если 20 процентов или меньше времени, заданного для завершения транзакции, остается, пакет фиксируется.

  • TransactionScopeRequired. При обработке пакета сообщений, если WCF обнаруживает сообщение, которое содержит TransactionScopeRequired = false, он фиксирует пакет и открывает новый пакет при получении первого сообщения с TransactionScopeRequired = true и TransactionAutoComplete = true.

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

Выход из режима пакетной обработки

Если сообщение в пакете приводит к прерыванию транзакции, выполните следующие действия:

  1. Весь пакет сообщений откатывается.

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

  3. Пакетный режим снова активирован.

Выбор размера пакета

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

Параллелизм и пакетная обработка

Чтобы увеличить пропускную способность, можно также одновременно запускать множество пакетов. Задав параметр ConcurrencyMode.MultipleServiceBehaviorAttribute, вы включите одновременную пакетную обработку.

Ограничение ресурсов службы — это поведение службы, которое используется для определения максимального количества одновременных вызовов. При использовании с пакетной обработкой это интерпретируется как количество одновременных пакетов. Если ограничение службы не задано, WCF по умолчанию устанавливает максимум 16 одновременных вызовов. Таким образом, если поведение пакетной обработки было добавлено по умолчанию, то в одно и то же время может быть активно не более 16 пакетов. Лучше всего настроить регулирование и пакетную обработку сервиса на основе ваших возможностей. Например, если в очереди есть 100 сообщений, а пакет из 20 требуется, максимальное число одновременных вызовов, равное 16, не полезно, так как в зависимости от пропускной способности 16 транзакций могут быть активными, аналогично тому, что пакетная обработка не включена. Таким образом, при точной настройке производительности либо не используйте параллельное пакетирование, либо используйте его с правильным размером ограничения службы.

Пакетная обработка и несколько конечных точек

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

Пример

В следующем примере показано, как указать TransactedBatchingBehavior в файле конфигурации.

<behaviors>
  <endpointBehaviors>
    <behavior name="TransactedBatchingBehavior"
              maxBatchSize="100" />
  </endpointBehaviors>
</behaviors>

В следующем примере показано, как определить TransactedBatchingBehavior в коде.

using (ServiceHost serviceHost = new ServiceHost(typeof(OrderProcessorService)))
{
     ServiceEndpoint sep = ServiceHost.AddServiceEndpoint(typeof(IOrderProcessor), new NetMsmqBinding(), "net.msmq://localhost/private/ServiceModelSamplesTransacted");
     sep.Behaviors.Add(new TransactedBatchingBehavior(100));

     // Open the ServiceHost to create listeners and start listening for messages.
    serviceHost.Open();
  
    // The service can now be accessed.
    Console.WriteLine("The service is ready.");
    Console.WriteLine("Press <ENTER> to terminate service.");
    Console.WriteLine();
    Console.ReadLine();
  
    // Close the ServiceHostB to shut down the service.
    serviceHost.Close();
}  

См. также