Compartilhar via


Desempenho do Windows Workflow Foundation 4

O .NET Framework 4 inclui uma revisão importante do WF (Windows Workflow Foundation) com investimentos pesados em desempenho. Essa nova revisão introduz alterações de design significativas de versões anteriores do WF fornecidos como parte do .NET Framework 3.0 e do .NET Framework 3.5. Foi re bem - principal do modelo, em runtime, e o trabalho feito com ferramentas de programação melhorar bastante o desempenho e a usabilidade. Este tópico mostra as características de desempenho importantes dessas revisões e compara-as com essas de versão anterior.

O desempenho componente de fluxo de trabalho individual disparou por pedidos de magnitude entre WF3 e WF4. Isso deixa a lacuna entre os serviços do WCF (Windows Communication Foundation) codificados à mão e os serviços de fluxo de trabalho do WCF bastante pequena. A latência de fluxo de trabalho foi reduzida significativamente em WF4. O desempenho de persistência gerado por um fator de 2,5 - 3,0. Monitoramento da integridade por meio de acompanhamento de fluxo de trabalho tem significativamente menos sobrecarga. Essas são razões de migrar ou peso a adotar WF4 em seus aplicativos.

Terminologia

A versão do WF introduzida no .NET Framework 4 será chamada como WF4 para o restante deste tópico. O WF foi introduzido no .NET Framework 3.0 e teve algumas revisões secundárias por meio do .NET Framework 3.5 SP1. A versão do .NET Framework 3.5 de base de fluxo de trabalho será chamada de WF3 para o restante deste tópico. O WF3 é fornecido no .NET Framework 4 lado a lado com o WF4. Para obter mais informações sobre como migrar artefatos do WF3 para o WF4, consulte: Guia de migração do Windows Workflow Foundation 4.

O WCF (Windows Communication Foundation) é o modelo de programação unificado da Microsoft para a criação de aplicativos orientados a serviços. Ele foi introduzido pela primeira vez como parte do .NET Framework 3.0 junto com o WF3 e agora é um dos principais componentes do .NET Framework.

Windows Server AppFabric é um conjunto de tecnologias integrados que tornam mais fácil criar, redimensionar e gerenciar Web e aplicativos compostos que executam no IIS. Fornece ferramentas para monitorar e gerenciar serviços e fluxos de trabalho. Para obter mais informações, consulte Windows Server AppFabric 1.0.

Metas

O objetivo deste tópico é mostrar as características de desempenho de WF4 com os dados medidas para diferentes cenários. Também fornece comparações detalhadas entre WF4 e WF3, e mostra o grandes aprimoramentos que foram feitas nessa nova revisão. Os cenários e os dados apresentados neste artigo determinam o custo subjacentes de diferentes aspectos de WF4 e de WF3. Esses dados são úteis para entender as características de desempenho de WF4 e podem ser úteis em migrações de planejamento de WF3 a WF4 ou WF4 de uso durante o desenvolvimento de aplicativos. No entanto, cuidado deve ser recolhido as conclusões desenhadas de dados apresentados neste artigo. O desempenho de um aplicativo de fluxo de trabalho composto é altamente dependente em como o fluxo de trabalho é implementado e como os diferentes componentes são integrados. Se deve abranger cada aplicativo para determinar as características de desempenho do aplicativo.

Visão geral dos aprimoramentos de desempenho WF4

WF4 cuidadosamente foi criado e implementado com alto desempenho e escalabilidade que são descritas nas seções.

Runtime de WF

O núcleo de runtime do WF é um agendador assíncrono que gera a execução das atividades em um fluxo de trabalho. Fornece um ambiente performant, previsível de execução para atividades. O ambiente tem um contrato bem definido para execução, a seguir, a conclusão, cancelamento, as exceções, e um modelo de threads previsível.

Em comparação com WF3, o runtime WF4 tem um agendador mais eficiente. Ele aproveita o mesmo pool de threads de E/S usado para o WCF, que é muito eficiente na execução de itens de trabalho em lote. A fila de agendador interna de item de trabalho é otimizado para a maioria de padrões comuns de uso. O runtime do WF4 também gerencia os estados de execução de maneira muito leve com a lógica mínima de sincronização e manipulação de eventos, enquanto o WF3 depende do registro de eventos de peso pesado e da invocação para executar uma sincronização complexa para transições de estado.

Armazenamento de dados e fluxo

Em WF3, os dados associados com uma atividade são modelados através das propriedades de dependência implementadas pelo tipo DependencyProperty. O padrão de propriedade de dependência foi introduzido no WPF (Windows Presentation Foundation). Normalmente, esse padrão é muito flexível dar suporte à associação fácil de dados e outros recursos de interface do usuário. No entanto, o padrão requer as propriedades ser definido como campos estáticos na definição de fluxo de trabalho. Sempre que o runtime do WF define ou obtém os valores de propriedade, ele envolve uma lógica de pesquisa fortemente ponderada.

Lógica clara do escopo de dados dos usos WF4 para melhorar bastante como os dados são tratados em um fluxo de trabalho. Separa os dados armazenados em uma atividade dos dados que estão de fluxo através de limites de atividade usando dois conceitos distintos: variáveis e argumentos. Usando um escopo hierárquico claro para variáveis e argumentos "In/Out/InOut", a complexidade de uso de dados para atividades é drasticamente reduzida e o tempo de vida dos dados também é definido automaticamente. As atividades tem uma assinatura bem definido descrita por seus argumentos. Simplesmente inspecionando uma atividade você pode determinar que espera dados e receber dados que serão gerados por eles como resultado da execução.

Nas atividades WF3 foram inicializados quando um fluxo de trabalho foi criado. Em atividades de WF 4 são inicializados somente quando as atividades correspondentes estão executando. Isto permite um ciclo de vida mais simples de atividade sem executar operações inicializa/Uninitialize quando uma nova instância de fluxo de trabalho é criada, e assim obtido em mais eficiência

Fluxo de Controle

Assim como em qualquer linguagem de programação, o WF dá suporte para fluxos de controle para definições de fluxo de trabalho introduzindo um conjunto de atividades de fluxo de controle para sequenciamento, loop, ramificação e outros padrões. Em WF3, quando a mesma atividade precisa ser executada, novo ActivityExecutionContext é criado e a atividade é clonada com uma lógica pesada de serialização e desserialização de baseada em BinaryFormatter. Geralmente o desempenho para fluxos de controle iterativos é muito mais lento do que executando uma sequência de atividades.

WF4 manipula esse bem diferente. Leva o modelo de atividade, cria um novo objeto de ActivityInstance, e adicioná-lo a fila de agendador. Todo esse processo envolve apenas a criação explícita de objetos e é muito leve.

Programação assíncrona

Os aplicativos geralmente têm um melhor desempenho e escalabilidade com programação assíncrona para operações longas de bloqueio como E/S ou operações distribuídos de computação. WF4 fornece suporte assíncrono por tipos de base AsyncCodeActivityde atividade, AsyncCodeActivity<TResult>. O runtime entende nativo que as atividades assíncronos e portanto podem automaticamente colocar a instância em uma zona sem persistir quando o trabalho assíncrono está excelente. As atividades personalizados podem derivar desses tipos para executar o trabalho assíncrona sem armazenar o segmento de agendador de fluxo de trabalho e bloquear quaisquer atividades que podem ser capaz executar paralelamente.

Mensagens

Inicialmente WF3 tinha muito suporte limitado de mensagem com as chamadas de eventos externos ou serviços da Web. No .NET Framework 3.5, os fluxos de trabalho podem ser implementados como clientes WCF ou expostos como serviços do WCF por meio de SendActivity e ReceiveActivity. No WF4, o conceito de programação de mensagens baseada em fluxo de trabalho foi ainda mais reforçado por meio da integração apertada da lógica de mensagens do WCF ao WF.

O pipeline de processamento de mensagens unificado fornecido no WCF no .NET 4 ajuda os serviços do WF4 a ter desempenho e escalabilidade significativamente melhores do que o WF3. WF4 também fornece um meio de programação mais sofisticado de mensagem que pode modelar padrão complexos (MEPs) de Exchange de mensagem. Os desenvolvedores podem usar contratos de serviço tipados para obter programação fácil ou contratos de serviço não tipados para obter melhor desempenho sem pagar custo de serialização. Suporte do lado do cliente de cachê do canal por meio da classe SendMessageChannelCache em desenvolvedores de ajuda WF4 criar aplicativos rápidos com esforço mínimo. Para obter mais informações, consulte Alterando os níveis de compartilhamento de cache para atividades de envio.

Programação declarativa

WF4 fornece uma estrutura declarativamente limpa e de programação simples para modelar processos comerciais e serviços. O modelo de programação oferece suporte a composição totalmente declarativa de atividades, sem nenhum código ao lado de simplificando, bastante a criação de fluxo de trabalho. No .NET Framework 4, a estrutura de programação declarativa baseada em XAML foi unificada no system.Xaml.dll de assembly único para dar suporte ao WPF e ao WF.

Em WF4, XAML fornece uma experiência realmente declarativamente e permite-à definição inteira de fluxo de trabalho ser definida na marcação XML, referenciando atividades e digitar .NET de usar compilado. Isso foi difícil de fazer em WF3 com formato de XOML sem quebrar o personalizado code-behind de lógica. A nova pilha XAML no .NET 4 tem um desempenho muito melhor na serialização/desserialização de artefatos de fluxo de trabalho e torna a programação declarativa mais atraente e sólida.

Designer de Fluxo de Trabalho

Suporte de programação completamente declarativo para WF4 aplicar explicitamente um mais altos requisitos para desempenho de tempo de design para grandes fluxos de trabalho. O designer de fluxo de trabalho em WF4 tem a escalabilidade muito melhor para grandes fluxos de trabalho do que aquela para WF3. Com suporte a virtualização de interface do usuário, o designer pode facilmente carregar um grande fluxo de trabalho 1000 atividades em alguns segundos, quando é quase impossível carregar um fluxo de trabalho algumas cem atividades com o designer WF3.

Comparações de desempenho de nível por componente

Esta seção contém dados em comparações diretas entre atividades individuais em fluxos de trabalho WF3 e WF4. Os pontos chave como a persistência tem um impacto no desempenho mais profundo dos componentes individuais de atividade. As melhorias de desempenho em componentes individuais em WF4 são importantes embora porque os componentes são agora rápidos o suficiente para ser comparados com a lógica mão- valor de orquestração. Um exemplo do qual é abordado na próxima seção: "Cenário de composição de serviço".

Configuração do ambiente

Environment setup for workflow performance measurement

A figura anterior mostra a configuração de máquina usada para medidas de desempenho de nível por componente. Um único servidor e cinco clientes conectados sobre uma interface de rede Ethernet 1-Gbps. Para medidas fáceis, o servidor é configurado para usar um único núcleo de um servidor dual-proc/quad-core executando o Windows Server 2008 x86. A utilização da CPU do sistema é mantida em quase 100%.

Detalhes do teste

O WF3 CodeActivity é provável a atividade a mais simples que pode ser usada em um fluxo de trabalho WF3. A atividade chama um método no code-behind que o programador de fluxo de trabalho pode colocar código em personalizado. Em WF4, não há analógico direto ao WF3 CodeActivity que fornece a mesma funcionalidade. Observe que há uma classe base de CodeActivity em WF4 que não está relacionado ao WF3 CodeActivity. Os autores de fluxo de trabalho são incentivados criar atividades personalizados e criar fluxos de trabalho XAML-only. Nos testes abaixo, uma atividade chamada Comment é usada no lugar de CodeActivity vazia em fluxos de trabalho WF4. O código na atividade de Comment é a seguinte:

[ContentProperty("Body")]
    public sealed class Comment : CodeActivity
    {
        public Comment()
            : base()
        {
        }

        [DefaultValue(null)]
        public Activity Body
        {
            get;
            set;
        }

        protected override void Execute(CodeActivityContext context)
        {
        }
    }

Fluxo de trabalho vazio

Este teste usa um fluxo de trabalho da sequência sem atividades filhos.

Única atividade

O fluxo de trabalho é um fluxo de trabalho da sequência que contém uma atividade filho. A atividade é CodeActivity sem código em casos WF3 e uma atividade de Comment em casos WF4.

Quando com 1000 iterações

O fluxo de trabalho da sequência contém uma atividade de While com uma atividade filho no loop que não executa qualquer trabalho.

Replicator comparou a ParallelForEach

ReplicatorActivity em WF3 tem modos de execução sequencial e paralela. No modo sequencial, o desempenho da atividade é semelhante a WhileActivity. ReplicatorActivity é mais útil para execução paralela. O WF4 analógico para essa é a atividade de ParallelForEach<T> .

O diagrama a seguir mostra os fluxos de trabalho usados para esse teste. O trabalho WF3 estão à esquerda e o trabalho WF4 estão à direita.

WF3 ReplicatorActivity and WF4 ParallelForEach

Fluxo de trabalho sequencial com cinco atividades

Este teste serve mostrar o efeito de ter várias atividades executa em ordem. Há cinco atividades na sequência.

Escopo de transação

O teste do escopo de transação diferem dos outros teste ligeiramente que uma nova instância de fluxo de trabalho não será criado para cada iteração. Em vez disso, o fluxo de trabalho seja estruturada com um loop de quando que contém uma atividade de TransactionScope que contém uma única atividade que não faz nenhum trabalho. Cada um execução de um lote de 50 iterações através de loop de quando for contagem como uma única operação.

Compensação

O fluxo de trabalho WF3 tem uma única atividade compensatable chamada WorkScope. A atividade simplesmente implementa a interface de ICompensatableActivity :

class WorkScope :
        CompositeActivity, ICompensatableActivity
    {
        public WorkScope() : base() { }

        public WorkScope(string name)
        {
            this.Name = name;
        }

        public ActivityExecutionStatus Compensate(
            ActivityExecutionContext executionContext)
        {
            return ActivityExecutionStatus.Closed;
        }
    }

O manipulador de falhas tem como destino a atividade de WorkScope. O fluxo de trabalho do WF4 é igualmente simplista. CompensableActivity tem um corpo e um manipulador de compensação. Um explícito compensa é seguir na sequência. A atividade de atividade de corpo e do manipulador de compensação é ambas são implementações:

public sealed class CompensableActivityEmptyCompensation : CodeActivity
    {
        public CompensableActivityEmptyCompensation()
            : base() { }

        public Activity Body { get; set; }

        protected override void Execute(CodeActivityContext context) { }
    }
    public sealed class CompensableActivityEmptyBody : CodeActivity
    {
        public CompensableActivityEmptyBody()
            : base() { }

        public Activity Body { get; set; }

        protected override void Execute(CodeActivityContext context) { }
    }

O diagrama a seguir mostra o fluxo de trabalho de compensação básico. O trabalho WF3 estão à esquerda e o trabalho WF4 estão à direita.

WF3 and WF4 basic compensation workflows

Resultados de testes de desempenho

Table showing performance test results data

Column chart comparing WF3 and WF4 performance test data

Todos os testes são medidos em por segundo de fluxos de trabalho com exceção de teste do escopo de transação. Como pode ser visto acima, o desempenho do runtime do WF melhorou em todo o quadro, especialmente em áreas que exigem várias execuções da mesma atividade, como o loop while.

Cenário de composição de serviço

Como é mostrado na seção anterior, "Comparações de desempenho no nível do componente", houve uma redução significativa na sobrecarga entre o WF3 e o WF4. Os serviços de fluxo de trabalho do WCF agora podem quase corresponder ao desempenho dos serviços WCF codificados à mão, mas ainda têm todos os benefícios do runtime do WF. Esse cenário de teste compara um serviço WCF com um serviço de fluxo de trabalho do WCF no WF4.

Serviço de Store online

Um dos pontos fortes do Windows Workflow Foundation é a capacidade de redigir processos usando vários serviços. Para esse exemplo, há um serviço online de armazenamento que orquestre duas chamadas técnicos para comprar um pedido. A primeira etapa é validar o pedido usando um ordem que valida o serviço. A segunda etapa é preencher a ordem usando um serviço de depósito.

Os dois serviços backend, a validação do serviço e o depósito os serviços de aplicativos, permanecem os mesmos para ambos os testes. A parte que muda é o serviço online de Store que executa a orquestração. Em um caso, o serviço é codificado à mão como um serviço WCF. Para o outro caso, o serviço é gravado como um serviço de fluxo de trabalho do WCF no WF4. Recursos específicos do WF, como acompanhamento e persistência, são desativados para este teste.

Ambiente

Environment setup for performance measurement

As solicitações de cliente são feitas para o serviço online de Store por HTTP vários computadores. Hosts únicos do computador todos os três serviços. A camada de transporte entre o serviço online de Store e serviços backend é TCP ou HTTP. A medida das operações/é baseada em dependendo do número de chamadas concluídos de PurchaseOrder feitas para o serviço online de Store. Pool de canal é um novo recurso disponível em WF4. Na parte do WCF deste pool de canais de teste não é fornecida fora da caixa, portanto, uma implementação codificada à mão de uma técnica de pool simples foi usada no Serviço de Repositório Online.

Desempenho

Column chart showing online Store Service performance

Conectando-se a serviços TCP de back-end sem pool de canais, o serviço WF tem um impacto de 17,2% na taxa de transferência. Com que o canal pool, a caneta é aproximadamente 23,8%. Para HTTP, o impacto é muito menos: 4,3% sem agrupamento e 8,1% com agrupamento. Também é importante observar que se agrupar do canal fornece muito pouco benefício ao usar HTTP.

Embora haja sobrecarga do runtime do WF4 em comparação com um serviço WCF codificado à mão neste teste, ele pode ser considerado um cenário pior. Os dois serviços backend neste teste torna muito pouco trabalho. Em um cenário de ponta a ponta real, esses serviços efetuariam um operações mais faces como chamadas de base de dados, fazendo o impacto de desempenho da camada de transporte menos importante. Isso mais os benefícios dos recursos disponíveis em WF4 faz a base de fluxo de trabalho uma alternativa viável para criar serviços de orquestração.

Considerações sobre desempenho principal

As áreas de recurso nesta seção, com exceção de interoperabilidade, bastante alterados entre WF3 e WF4. Isso afeta o design de aplicativos de fluxo de trabalho assim como o desempenho.

Latência de ativação de fluxo de trabalho

Em um aplicativo de serviço de fluxo de trabalho do WCF, a latência para iniciar um novo fluxo de trabalho ou carregar um fluxo de trabalho existente é importante, pois pode causar bloqueios. Essa situação de teste mede um host de WF3 XOML contra um host de WF4 XAMLX em um cenário típico.

Configuração do ambiente

Environment setup for latency and throughput tests

Configuração de teste

No cenário, um computador cliente entra em contato com um serviço de fluxo de trabalho do WCF usando correlação baseada em contexto. Correlação de contexto requer uma associação especial de contexto e usa um cabeçalho de contexto ou o cookie para relacionar mensagens ao fluxo de trabalho correto instância. Tem um benefício de desempenho que a identificação de correlação está localizada no cabeçalho de mensagem para que o corpo da mensagem não precisa ser analisado.

O serviço criará um novo fluxo de trabalho com a solicitação e enviará uma resposta imediata de modo que a medida de latência não inclua o tempo gasto executando o fluxo de trabalho. O trabalho WF3 são XOML com a code-behind e o trabalho WF4 são totalmente XAML. Os aspectos de fluxo de trabalho WF4 como este:

WF4 Correlation Scope workflow

A atividade de Receive cria a instância de fluxo de trabalho. Um valor passado a mensagem é recebida ecoado na mensagem de resposta. Uma sequência após a resposta contém o resto de fluxo de trabalho. Em casos anterior, somente uma atividade do comentário é mostrada. O número de atividades de comentário é alterado para simular a complexidade de fluxo de trabalho. Uma atividade do comentário é equivalente a um WF3 CodeActivity que não executa qualquer trabalho. Para obter mais informações sobre a atividade de comentário, consulte a seção "Comparação de desempenho no nível do componente" anteriormente neste artigo.

Resultados do teste

Latência fria e quente para serviços de fluxo de trabalho do WCF:

Column chart showing cold and warm latency for WCF workflow services using WF3 and WF4

No gráfico anterior, frio refere-se ao caso em que não há uma WorkflowServiceHost existente para o fluxo de trabalho especificado. Ou seja a latência fria é quando o fluxo de trabalho está sendo usado pela primeira vez e o XOML ou o XAML precisam ser compilados. A latência morna é o tempo de criação de uma nova instância de fluxo de trabalho quando o tipo de fluxo de trabalho já foi criado. A complexidade de fluxo de trabalho faz a diferença muito pequena em casos WF4 mas tem uma progressão linear em casos WF3.

Rendimento de correlação

WF4 apresenta um novo recurso base de conteudo correlação. WF3 de contexto fornecido com apenas correlação. A correlação baseada em contexto só poderia ser feita em associações de canal WCF específicas. A identificação do fluxo de trabalho é inserida no cabeçalho de mensagem para usar essas associações. O runtime do WF3 só pôde identificar um fluxo de trabalho por sua ID. Com a correlação baseada em conteúdo, o autor do fluxo de trabalho pode criar uma chave de correlação com base em um dado relevante, como um número de conta ou uma ID do cliente.

Correlação de contexto base tem uma vantagem de desempenho que a chave de correlação está localizada no cabeçalho de mensagem. A chave pode ser lido de mensagem sem de- serialização/mensagem- copiar. Em correlação conteudo base, a chave de correlação é armazenada no corpo da mensagem. Uma expressão XPath é usada para localizar a chave. O custo desse processamento adicional depende do tamanho de mensagem, profundidade de chave no corpo, e o número de chaves. Este teste compara contexto e correlação conteudo base e também mostra degradação de desempenho ao usar várias chaves.

Configuração do ambiente

Environment setup for workflow performance test

Configuração de teste

Correlation Throughput Workflow Test

O fluxo de trabalho anterior é o mesmo usado na seção Persistência. Para os testes de correlação sem persistência, não há nenhum provedor de persistência instalado no runtime. Correlação ocorre em dois locais: CreateOrder e CompleteOrder.

Resultados do teste

Correlation Throughput

Este gráfico a seguir mostra um decréscimo de desempenho como o número de chaves usadas em correlação conteudo base aumenta. A semelhança em curvas entre o TCP e o HTTP indica a sobrecarga associada com esses protocolos.

Correlação com persistência

Com um fluxo de trabalho persistente, pressão CPU de conteudo correlação desloca com base em runtime de fluxo de trabalho a base de dados SQL. Os procedimentos armazenados no provedor de persistência do SQL faça o trabalho de combinar as chaves para localizar o fluxo de trabalho apropriado.

Line chart showing correlation and persistence results

Correlação de contexto base ainda é mais rápido que correlação conteudo base. No entanto, a diferença é pronunciada menos porque a persistência tem mais impacto no desempenho que correlação.

Produção complexa de fluxo de trabalho

A complexidade de um fluxo de trabalho não é medida somente pelo número de atividades. As atividades compostas podem conter muitos filhos e os filhos podem também ser atividades compostas. Como o número de níveis de aninhamento aumenta, o que faz o número de atividades que podem estar executando atualmente no estado e o número de variáveis que podem estar em estado. Este teste compara a produção entre WF3 e WF4 ao executar fluxos de trabalho complexos.

Configuração de teste

Esses testes foram executados em um computador de maneira 2.66GHz 4 Intel Xeon X5355 @ com 4GB RAM executando Windows Server 2008 86. O código de teste é executado em um único processo com um segmento pelo núcleo para atingir o uso da CPU 100%.

Fluxos de trabalho gerados para esse teste têm duas variáveis principais: profundidade e número de atividades em cada sequência. Cada nível de profundidade incluir uma atividade paralela, quando loop, decisões, atribuições, e sequências. No designer WF4 representado abaixo, o fluxograma de nível superior é representado. Cada atividade do fluxograma lembra o fluxograma principal. Pode ser útil pensar em um fractal para representar este fluxo de trabalho, onde a profundidade é limitada aos parâmetros de teste.

O número de atividades em um teste dado é determinado por profundidade e o número de atividades pela sequência. A equação seguir calcula o número de atividades no teste WF4:

Equation to compute number of activities

A contagem de atividade de teste WF3 pode ser computado com uma equação ligeiramente diferente devido a uma sequência extra:

Equation to compute number of WF3 activities

De onde está o tamanho e a são o número de atividades pela sequência. A lógica por trás dessas equações é que a primeira constante, multiplicada por, é o número de sequências e a segunda constante é o número de atividades estático no nível atual. Há três atividades filhos do fluxograma em cada fluxograma. A nível inferior de profundidade, esses fluxogramas estão vazios mas a outros níveis são cópias do fluxograma principal. O número de atividades na definição de fluxo de trabalho de cada variação de teste é indicado na tabela a seguir:

A table that shows the number of activities used in each test

O número de atividades na definição de fluxo de trabalho aumenta com nitidez com cada nível de profundidade. Mas somente um caminho pelo ponto de decisão é executado em uma determinada instância de fluxo de trabalho, portanto somente um subconjunto pequeno de atividades reais é executado.

Flowchart of the complex throughput workflow

Um fluxo de trabalho equivalente foi criado para WF3. O designer WF3 mostra o fluxo de trabalho inteiro na área de design em vez de aninhamento, portanto é muito grande exibir neste tópico. Um snippet de fluxo de trabalho é mostrado abaixo.

Flowchart snippet of the WF3 workflow

Para exercitar aninhamento em casos, extremos outro fluxo de trabalho que seja parte dos usos 100 deste teste tivesse sequências. Na sequência interno são único Comment ou CodeActivity.

Flowchart of a nested sequence

O rastreamento e a persistência não são usados como parte deste teste.

Resultados do teste

Column chart showing throughput performance results

Mesmo com fluxos de trabalho complexos com muitos de profundida e um número alto de atividades, os resultados de desempenho são consistentes com outros números de produção mostradas anteriormente neste artigo. A taxa de WF4 é pedidos de magnitude mais rapidamente e tem que ser comparadas em uma escala logarítmica.

Memória

A sobrecarga de memória do Windows Workflow Foundation é medida em dois pontos chave: complexidade de fluxo de trabalho e número de definições de fluxo de trabalho. As medidas de memória foram executadas em uma estação de trabalho de 64 bits do Windows 7. Há muitas maneiras de obter a medida do tamanho do conjunto de trabalho, como monitorar contadores de desempenho, sondar Environment.WorkingSet ou usar uma ferramenta como VMap disponível no VMMap. Uma combinação de métodos foi usada para obter e verificar os resultados de cada teste.

Teste a complexidade de fluxo de trabalho

O teste de complexidade de fluxo de trabalho mede a diferença de conjunto de trabalho baseado em complexidade de fluxo de trabalho. Além dos fluxos de trabalho complexo usados na seção anterior, as novas variações são adicionados para cobrir dois casos básicos: um único fluxo de trabalho de atividade e uma sequência com 1000 atividades. Para esses testes fluxos de trabalho são inicializados e executados para a conclusão em um único loop serial por um período de um minuto. Cada variação de teste é executada três vezes e os dados são gravados a média dessas três é executado.

Os dois novos teste básicos têm fluxos de trabalho que são como aqueles mostrados abaixo:

Complex workflow for both WF3 and WF4

No fluxo de trabalho WF3 mostrado acima, as atividades vazios de CodeActivity são usadas. As atividades acima de Comment usos de fluxo de trabalho WF4. A atividade de Comment foi descrito na seção comparações de desempenho de nível por componente anteriormente neste artigo.

Column chart showing complex workflow memory usage for WF3 and WF4 workflows

Uma das tendências claras observar no gráfico é que se aninhar relativamente tem impacto mínimo sobre o uso de memória em WF3 e em WF4. O impacto o mais significativa de memória do número de atividades em um determinado fluxo de trabalho. Dado os dados da sequência 1000, a sequência complexa 5 profundidade 5, e profundidade complexa 7 variações da sequência 1, é claro como o número de atividades inserir milhares, increase de uso de memória ficar mais visível. Em casos extremos sequência 1 (profundidade 7) onde há atividades de ~29K, WF4 estiver usando quase 79% menos memória que WF3.

Vários teste das definições de fluxo de trabalho

Medir a memória pela definição de fluxo de trabalho é dividido em dois diferentes teste devido às opções disponíveis para hospedar fluxos de trabalho em WF3 e em WF4. Os testes são rodados de maneira diferente do teste de complexidade de fluxo de trabalho que um fluxo de trabalho já está citado como exemplo e executado somente uma vez por definição. Isso ocorre porque a definição de fluxo de trabalho e seu host permanecem em memória para o tempo de vida de Appdomain. A memória usado executando uma determinada instância de fluxo de trabalho deve ser removida durante a coleta de lixo. A orientação de migração para WF4 contém informações mais detalhadas sobre as opções de hospedagem. Para obter mais informações, consulte o Guia de Migração do WF: hospedagem de fluxo de trabalho.

Criar várias definições de fluxo de trabalho para um teste de definição de fluxo de trabalho pode ser feita em várias maneiras. Por exemplo, um pode usar a geração de código para criar um conjunto de 1000 fluxos de trabalho que são idênticos exceto no nome e para salvar cada um desses fluxos de trabalho em arquivos separados. Essa abordagem foi tirada para teste console- hospedado. Em WF3, a classe de WorkflowRuntime foi usada para executar as definições de fluxo de trabalho. WF4 pode usar WorkflowApplication para criar uma instância única de fluxo de trabalho ou usar diretamente WorkflowInvoker para executar a atividade como se fosse um chamada de método. WorkflowApplication é um host de uma única instância de fluxo de trabalho e tem mais próximo uma paridade recurso a WorkflowRuntime de modo que é usado neste teste.

Para hospedar fluxos de trabalho no IIS é possível usar VirtualPathProvider para criar um novo WorkflowServiceHost em vez de gerar todos os arquivos de XAMLX ou de XOML. O VirtualPathProvider manipula a solicitação de entrada e responde com um "arquivo virtual" que pode ser carregado de um banco de dados ou, nesse caso, gerado em tempo real. Portanto é desnecessário criar arquivos 1000 físico.

As definições de fluxo de trabalho usadas no teste de console foram fluxos de trabalho sequenciais simples com uma única atividade. A única atividade foi CodeActivity vazio para as caixas WF3 e uma atividade de Comment para casos WF4. Configuração dos casos hospedados usaram fluxos de trabalho que começam em receber uma mensagem e terminam em enviar uma resposta:

A imagem a seguir mostra um fluxo de trabalho do WF3 com ReceiveActivity e um fluxo de trabalho WF4 com padrão de solicitação/resposta:

Workflow Services in WF3 and WF4

A tabela a seguir mostra o delta no conjunto de trabalho entre uma única definição de fluxo de trabalho e definições de 1001:

Hospedando opções Delta do conjunto de trabalho WF3 Delta do conjunto de trabalho WF4
Fluxos de trabalho hospedados do aplicativo de console 18 MB 9 MB
O IIS hospedou serviços de fluxo de trabalho 446 MB 364 MB

A hospedagem de definições de fluxo de trabalho no IIS consome muito mais memória devido à WorkflowServiceHost, artefatos detalhados do serviço WCF e à lógica de processamento de mensagens associada ao host.

Para o console que hospeda em WF3 fluxos de trabalho foram implementados no código em vez de XOML. Em WF4 a opção é usar XAML. O XAML livre é armazenado como um recurso inserido no assembly compilado e durante o runtime para fornecer a implementação de fluxo de trabalho. Há uma sobrecarga associada a este processo. Para fazer uma comparação entre justa WF3 e WF4, os fluxos de trabalho codificados foram usados em vez de XAML. Um exemplo de um dos fluxos de trabalho WF4 é mostrado abaixo:

public class Workflow1 : Activity
{
    protected override Func<Activity> Implementation
    {
        get
        {
            return new Func<Activity>(() =>
            {
                return new Sequence
                {
                    Activities = {
                        new Comment()
                    }
                };
            });
        }
        set
        {
            base.Implementation = value;
        }
    }
}

Há muitos outros fatores que podem afetar o consumo de memória. Conselhos o mesmo para todos os programas gerenciados ainda se aplica. A configuração em ambientes hospedados, o objeto de WorkflowServiceHost criado para uma definição de fluxo de trabalho permanece na memória até que o pool de aplicativos é reciclado. Isso deve ser mantido em mente ao escrever extensões. Além disso, é melhor evitar variáveis "globais" (variáveis com escopo para todo o fluxo de trabalho) e limitar o escopo de variáveis sempre que possível.

Serviços de runtime de fluxo de trabalho

Persistência

WF3 e WF4 ambos são fornecidas com um provedor de persistência SQL. O provedor de persistência WF3 SQL é uma implementação simples que serialize a instância de fluxo de trabalho e o armazena em uma operação. Por esse motivo, o desempenho desse provedor intensamente depende do tamanho de instância de fluxo de trabalho. Em WF3, o tamanho da instância pode aumentar por muitas razões, como é discutido anteriormente neste documento. Vários clientes escolha para não usar o provedor de persistência padrão de SQL como armazenar uma instância serializado em uma base de dados não fornece nenhuma visibilidade no estado de fluxo de trabalho. Para localizar um trabalho específicos sem conhecer a identificação de trabalho, uma teria que desserializar cada instância armazenado e examinar o conteúdo. Muitos desenvolvedores preferem escrever seus próprios provedores de persistência para superar essa obstáculo.

O provedor de persistência WF4 SQL tenta resolver alguns desses interesses. As tabelas de persistência expõe determinada informações como os indicadores ativos e as propriedades promotable. O novo recurso de conteudo baseado em WF4 correlação não deseja executar bem usando a abordagem de persistência WF3 SQL, que fez alterações na organização de instância persistentes de fluxo de trabalho. Isso torna o provedor de persistência mais complexos e coloca o esforço extra na base de dados.

Configuração do ambiente

Environment setup for workflow performance test

Configuração de teste

Mesmo com um conjunto aprimorado de recurso e uma melhor manipulação de concorrência, o provedor de persistência SQL em WF4 é mais rápido do que o provedor em WF3. Para apresentar isso, dois fluxos de trabalho executando essencialmente as mesmas operações em WF3 e em WF4 são comparados abaixo.

Persistence workflow in WF3 on left and WF4 on right

Os dois fluxos de trabalho ambos são criados por uma mensagem recebida. Após enviar uma resposta inicial, o fluxo de trabalho é mantido. Em casos WF3, TransactionScopeActivity vazia é usado para iniciar a persistência. O mesmo poderia ser alcançado no WF3 marcando uma atividade como "persistir no fechamento". Uma segunda mensagem correlacionada conclui o fluxo de trabalho. Fluxos de trabalho são persistidos mas não descarregados.

Resultados do teste

Column chart showing throughput persistence

Quando o transporte entre o cliente e a camada intermediária é HTTP, a persistência em WF4 mostra uma melhoria de 2,6 vezes. O transporte TCP aumenta o fator a 3,0 vezes. Em todos os casos, a utilização da CPU na camada intermediária é 98% ou maior. A razão para a produção WF4 é maior realiza-se devido ao runtime mais rápido de fluxo de trabalho. O tamanho da instância é serializado baixo para ambos os casos e não é um elemento de contribuição principal nesta situação.

WF3 e fluxos de trabalho WF4 neste teste usam uma atividade para indicar explicitamente quando a persistência deve ocorrer. Isso tem a vantagem de persistir o fluxo de trabalho sem descarregá-lo. Em WF3, também é possível persistir usando o recurso de TimeToUnload , mas este descarrega a instância de fluxo de trabalho de memória. Se um desenvolvedor que usa WF3 deseja verificar se um fluxo de trabalho persiste em determinados pontos, tem que alterar a definição de fluxo de trabalho ou pagar o custo descarregar e recarregar a instância de fluxo de trabalho. Um novo recurso em WF4 possibilita persistir sem descarregar: TimeToPersist. Esse recurso permite que a instância de fluxo de trabalho está armazenado em ociosa mas é na memória até que o limite de TimeToUnload está localizado ou a execução é continuada.

Observe que o provedor de persistência WF4 SQL executa mais trabalho na camada de base de dados. O base de dados SQL pode se tornar um gargalo portanto é importante monitorar existem o uso da CPU e o disco. Certifique-se de incluir os seguintes contadores de desempenho de base de dados SQL quando aplicativos de fluxo de trabalho de teste de desempenho:

  • Tempo de leitura de PhysicalDisk \ %Disk

  • PhysicalDisk \ % de tempo de disco

  • PhysicalDisk \ de disco % de gravação

  • PhysicalDisk\% Avg. Comprimento da fila de disco

  • PhysicalDisk\Avg. Comprimento da fila de leitura do disco

  • PhysicalDisk\Avg. Comprimento da fila de gravação de disco

  • PhysicalDisk \ comprimento atual da fila de disco

  • Informações do Processador\% Tempo do Processador

  • SQLServer: Travas \ tempo de espera trava de média (ms)

  • SQLServer: Travas \ espera por de trava/s

Acompanhamento

O rastreamento de fluxo de trabalho pode ser usado para acompanhar o progresso de um fluxo de trabalho. Informações que está incluída em eventos de rastreamento é determinada por um perfil de rastreamento. Mais complexo o perfil de rastreamento, mais caro o rastreamento fica.

WF3 enviados com um serviço SQL- base de rastreamento. Esse serviço pode trabalhar nos modos processados em lotes e não processados em lotes. No modo não processado em lotes, controlando eventos são gravados diretamente a base de dados. No modo processado em lotes, controlando eventos são coletados em lotes mesmo que o estado da instância de fluxo de trabalho. O modo processado em lotes tem um desempenho melhor para o intervalo o maior de projetos de fluxo de trabalho. No entanto, em lotes pode ter um impacto de desempenho negativo se o fluxo de trabalho executa muitos atividades sem persistir e as atividades são rastreadas. Isso geralmente aconteceria em loop e a melhor maneira para evitar esse cenário é criar grandes loop para conter um ponto de persistência. Introduzir um ponto de persistência em um loop pode afetar negativamente o desempenho também portanto é importante medir o custo de cada e vir anterior com um balanço.

WF4 não é enviado com um serviço de rastreamento SQL. Registrar informações de acompanhamento em um banco de dados SQL pode ser tratado melhor de um servidor de aplicativos em vez de integrado ao .NET Framework. Portanto o rastreamento SQL é tratado agora por AppFabric. O provedor pronto para uso de rastreamento em WF4 é baseado no rastreamento de evento para o Windows (ETW).

ETW é um kernel- nível, o sistema de evento de baixo latência compilado no Windows. Usa um modelo de provedor/consumidor que execute possível incorrer somente a caneta para o rastreamento de evento quando há realmente um consumidor. Além de eventos kernel como o processador, o disco, a memória, e o uso de rede, muitos aplicativos aproveitam ETW também. Os eventos de ETW são mais avançados de contadores de desempenho que os eventos podem ser personalizados para o aplicativo. Um evento pode conter texto como uma identificação de fluxo de trabalho ou uma mensagem informativa. Além disso, os eventos são categorizados com máscaras de bits de modo que consumir um certo subconjunto de eventos menos tenha impacto de desempenho de tratar todos os eventos.

As vantagens de usar a abordagem ETW para controlar em vez do SQL incluem:

  • A coleção de eventos de rastreamento pode ser separada para outro processo. Isso proporciona maior flexibilidade de como os eventos são gravados.

  • Os eventos de acompanhamento de ETW são facilmente combinados com os eventos ETW do WCF ou outros provedores ETW, como um SQL Server ou um provedor de kernel.

  • Os autores de fluxo de trabalho não precisam modificar um fluxo de trabalho melhor para trabalhar com uma implementação específica de rastreamento, como o modo em lotes de serviço de rastreamento de WF3 SQL.

  • Um administrador pode girar de acompanhar ou sem reciclar o processo host.

Os benefícios de desempenho ao rastreamento de ETW vêm com um desvantagem. Os eventos de ETW podem ser perdidas se o sistema está sob a pressão intensa de recurso. O processamento de eventos não serve bloquear a execução do programa normal e portanto não se garante que todos os eventos de ETW serão passados para seus assinantes. Isso torna acompanhar de ETW grande para o monitoramento da integridade mas não para fazer auditoria em apropriado.

Quando WF4 não possui um provedor de rastreamento SQL, AppFabric faz. A abordagem de rastreamento SQL de AppFabric é assinar eventos de ETW com um serviço do Windows que processa em lotes os eventos e os escrevam a uma tabela SQL criada para inserções rápido possível. Um trabalho separados sai os dados da tabela e reformam-nos nas tabelas de relatório que podem ser exibidas no painel de AppFabric. Isso significa que um lote de eventos de rastreamento é tratado independente de fluxo de trabalho proveniente de e portanto não tenha que aguardar um ponto de persistência antes de ser gravado.

Os eventos de ETW podem ser gravados com ferramentas como o logman ou o xperf. O arquivo de compacto ETL pode ser exibido com uma ferramenta como o xperfview ou ser convertido em um formato mais legível, como XML, com tracerpt. Em WF3, a única opção para obter eventos de rastreamento sem um base de dados SQL é criar um serviço personalizado de rastreamento. Para obter mais informações sobre o ETW, consulte Serviços WCF e o Rastreamento de Eventos para Windows e Rastreamento de Eventos – aplicativos do Windows.

Ativar o rastreamento de fluxo de trabalho irá afetar o desempenho em vários níveis. A marca de nível abaixo usar a ferramenta de logman para consumir eventos de rastreamento de ETW e para gravar-los a um arquivo de ETL. O custo de rastreamento SQL em AppFabric não está no escopo deste artigo. O perfil básico de rastreamento, também usado em AppFabric, é mostrada nessa marca de nível. Também estão incluídos o custo de acompanhar somente eventos de monitoramento de integridade. Esses eventos são úteis para solucionar problemas e determinar a taxa média do sistema.

Configuração do ambiente

Environment setup for workflow performance test

Resultados do teste

Column chart showing workflow tracking costs

Monitoramento da integridade tem um impacto de aproximadamente 3% em produção. Os custos de perfil básico são aproximadamente 8%.

Interoperabilidade

O WF4 é quase uma reescrita completa do WF e, portanto, os fluxos de trabalho e as atividades do WF3 não são diretamente compatíveis com o WF4. Muitos clientes que adotaram o Windows Workflow Foundation mais cedo terão definições internas ou de fluxo de trabalho de terceiros e atividades personalizadas para o WF3. Uma maneira de fazer a transição para WF4 é usar a atividade de Interoperabilidade, que pode executar as atividades WF3 de dentro de um fluxo de trabalho WF4. É recomendável que a atividade de Interop seja usada somente quando necessário. Para obter mais informações sobre como migrar para o WF4, confira as Diretrizes de Migração do WF4.

Configuração do ambiente

Environment setup for workflow performance test

Resultados do teste

A tabela a seguir mostra os resultados da execução de um fluxo de trabalho contendo cinco atividades em uma sequência em várias configurações.

Teste Produção (fluxos de trabalho/s)
Sequência WF3 em runtime WF3 1.576
Sequência WF3 em runtime WF4 usando Interoperabilidade 2.745
Sequência WF4 153.582

Há um aumento notável de desempenho ao uso de Interoperabilidade sobre WF3 reto. No entanto, quando comparado com as atividades WF4, increase é irrisória.

Resumo

Os sejam investimentos no desempenho para WF4 pagaram fora em muitas áreas cruciais. O desempenho do componente de fluxo de trabalho individual é, em alguns casos, centenas de vezes mais rápido no WF4 em comparação com o WF3 devido a um runtime de WF mais enxuto. Números de latência é significativamente melhor também. Isso significa que a penalidade de desempenho por usar o WF em vez de codificar manualmente os serviços de orquestração do WCF é muito pequena considerando os benefícios adicionais do uso do WF. O desempenho de persistência gerado por um fator de 2,5 - 3,0. Monitoramento da integridade por meio de fluxo de trabalho que acompanha agora tem a sobrecarga muito pequena. Um conjunto abrangente de guias de migração está disponível para aqueles que estão considerando mover de WF3 a WF4. Qualquer esta deve fazer o WF4 uma opção atrativas para escrever aplicativos complexos.