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


Объединение сообщений в одну транзакцию

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

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

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

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

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

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

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

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

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

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

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

  1. Производится откат всего пакета сообщений.

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

  3. Производится повторный вход в пакетный режим.

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

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

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

Для увеличения пропускной способности возможна также параллельная обработка нескольких пакетов. Задав значение ConcurrencyMode.Multiple в атрибуте ServiceBehaviorAttribute, можно включить параллельную пакетную обработку.

Регулирование служб — это поведение службы, которое используется для указания максимального количества одновременных вызовов в службе. При использовании с пакетной обработкой это означает количество параллельно обрабатываемых пакетов. Если регулирование службы не задано, 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();
}  

См. также