Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
O .NET Framework 4 inclui uma revisão importante do WF (Windows Workflow Foundation) com investimentos pesados em desempenho. Essa nova revisão apresenta alterações significativas de design das versões anteriores do WF que foram enviadas como parte do .NET Framework 3.0 e do .NET Framework 3.5. Ela foi reprotetada do núcleo do modelo de programação, do runtime e das ferramentas para melhorar muito o desempenho e a usabilidade. Este tópico mostra as características de desempenho importantes dessas revisões e as compara com as da versão anterior.
O desempenho individual do componente de fluxo de trabalho aumentou por ordens de magnitude entre o WF3 e o WF4. Isso faz com que a lacuna entre os serviços do Windows Communication Foundation (WCF) codificados à mão e os serviços de fluxo de trabalho do WCF seja relativamente pequena. A latência do fluxo de trabalho foi significativamente reduzida no WF4. O desempenho de persistência aumentou em um fator de 2,5 a 3,0. O monitoramento de integridade por meio do acompanhamento de fluxo de trabalho tem significativamente menos sobrecarga. Esses são motivos convincentes para migrar ou adotar o WF4 em seus aplicativos.
Terminologia
A versão do WF introduzida no .NET Framework 4 será conhecida como WF4 para o restante deste tópico. O WF foi introduzido no .NET Framework 3.0 e teve algumas pequenas revisões por meio do .NET Framework 3.5 SP1. A versão do .NET Framework 3.5 do Workflow Foundation será conhecida como 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.
O AppFabric do Windows Server é um conjunto de tecnologias integradas que facilitam a criação, dimensionamento e gerenciamento de aplicativos Web e compostos executados no IIS. Ele fornece ferramentas para monitorar e gerenciar serviços e fluxos de trabalho. Para obter mais informações, consulte o Windows Server AppFabric 1.0.
Metas
O objetivo deste tópico é mostrar as características de desempenho do WF4 com dados medidos para cenários diferentes. Ele também fornece comparações detalhadas entre o WF4 e o WF3 e, portanto, mostra as grandes melhorias que foram feitas nesta nova revisão. Os cenários e os dados apresentados neste artigo quantificam o custo subjacente de diferentes aspectos do WF4 e do WF3. Esses dados são úteis para entender as características de desempenho do WF4 e podem ser úteis no planejamento de migrações do WF3 para o WF4 ou no uso do WF4 no desenvolvimento de aplicativos. No entanto, deve-se tomar cuidado com as conclusões obtidas dos dados apresentados neste artigo. O desempenho de um aplicativo de fluxo de trabalho composto depende muito de como o fluxo de trabalho é implementado e de como diferentes componentes são integrados. É necessário medir cada aplicativo para determinar as características de desempenho desse aplicativo.
Visão geral dos aprimoramentos de desempenho do WF4
O WF4 foi cuidadosamente projetado e implementado com alto desempenho e escalabilidade descritos nas seções a seguir.
Runtime de WF
No núcleo do runtime do WF está um agendador assíncrono que conduz a execução das atividades em um fluxo de trabalho. Ele fornece um ambiente de execução de alto desempenho e previsível para atividades. O ambiente tem um contrato bem definido para execução, continuação, conclusão, cancelamento, exceções e um modelo de threading previsível.
Em comparação com o WF3, o runtime do 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 do agendador de item de trabalho interno é otimizada para a maioria dos padrões de uso comuns. O runtime do WF4 também gerencia os estados de execução de maneira simplificada com lógica mínima de sincronização e tratamento de eventos, enquanto o WF3 depende do registro e invocação de eventos de alta intensidade para realizar uma sincronização complexa nas transições de estado.
Armazenamento e Fluxo de Dados
No WF3, os dados associados a uma atividade são modelados por meio de propriedades de dependência implementadas pelo tipo DependencyProperty. O padrão de propriedade de dependência foi introduzido no WPF (Windows Presentation Foundation). Em geral, esse padrão é muito flexível para dar suporte à associação de dados fácil e a outros recursos de interface do usuário. No entanto, o padrão requer que as propriedades sejam definidas como campos estáticos na definição do 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.
O WF4 usa uma lógica de escopo de dados clara para melhorar muito a maneira como os dados são tratados em um fluxo de trabalho. Ele separa os dados armazenados em uma atividade dos dados que estão fluindo entre os limites de atividade usando dois conceitos diferentes: variáveis e argumentos. Usando um escopo hierárquico claro para variáveis e argumentos "In/Out/InOut", a complexidade do uso de dados para atividades é drasticamente reduzida, e o tempo de existência dos dados também é definido automaticamente. As atividades têm uma assinatura bem definida descrita por seus argumentos. Ao simplesmente inspecionar uma atividade, você pode determinar quais dados ele espera receber e quais dados serão produzidos por ela como resultado de sua execução.
Nas atividades do WF3 foram inicializadas quando um fluxo de trabalho foi criado. No WF 4, as atividades são inicializadas apenas quando as atividades correspondentes estão em execução. Isso permite um ciclo de vida de atividade mais simples sem executar operações Inicializar/Uninitializar quando uma nova instância de fluxo de trabalho é criada e, portanto, tem obtido mais eficiência
Fluxo de Controle
Assim como em qualquer linguagem de programação, o WF fornece 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. No WF3, quando a mesma atividade precisa ser executada novamente, uma nova ActivityExecutionContext é criada e a atividade é clonada por meio de uma lógica de serialização e desserialização pesada baseada em BinaryFormatter. Normalmente, o desempenho para fluxos de controle iterativo é muito mais lento do que executar uma sequência de atividades.
O WF4 lida com isso de forma bem diferente. Ele usa o modelo de atividade, cria um novo objeto ActivityInstance e o adiciona à fila do 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 melhor desempenho e escalabilidade com programação assíncrona para operações de bloqueio de execução longa, como E/S ou operações de computação distribuídas. O WF4 fornece suporte assíncrono por meio de tipos de atividade base AsyncCodeActivity, 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 personalizadas podem derivar desses tipos para executar um trabalho assíncrono sem manter o thread do agendador de fluxo de trabalho e bloquear as atividades que possam ser executadas em paralelo.
Mensagens
Inicialmente, o WF3 tinha suporte de mensagens muito limitado por meio de eventos externos ou invocações de serviços Web. No .NET Framework 3.5, os fluxos de trabalho podem ser implementados como clientes WCF ou expostos como serviços WCF por meio 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. O WF4 também fornece suporte mais avançado à programação de mensagens que pode modelar padrões complexos de Troca de Mensagens (MEPs). Os desenvolvedores podem usar contratos de serviço tipados para obter uma programação fácil ou contratos de serviço não tipados para obter um melhor desempenho sem pagar custos de serialização. O suporte ao cache de canal do lado do cliente por meio da SendMessageChannelCache classe no WF4 ajuda os desenvolvedores a criar aplicativos rápidos com o mínimo de esforço. Para obter mais informações, consulte Alterando os níveis de compartilhamento de cache para atividades de envio.
Programação declarativa
O WF4 fornece uma estrutura de programação declarativa limpa e simples para modelar processos e serviços de negócios. O modelo de programação dá suporte à composição totalmente declarativa das atividades, sem adição de código, simplificando muito a criação de fluxo de trabalho. No .NET Framework 4, a estrutura de programação declarativa baseada em XAML foi unificada em um único assembly System.Xaml.dll para suportar tanto o WPF quanto o WF.
No WF4, o XAML fornece uma experiência verdadeiramente declarativa e permite que toda a definição do fluxo de trabalho seja definida na marcação XML, referenciando atividades e tipos criados usando o .NET. 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
O suporte de programação totalmente declarativa para WF4 impõe explicitamente requisitos mais altos para o desempenho de tempo de design para grandes fluxos de trabalho. O designer de fluxo de trabalho no WF4 tem uma escalabilidade muito melhor para fluxos de trabalho grandes do que para o WF3. Com o suporte à virtualização da interface do usuário, o designer pode carregar facilmente um grande fluxo de trabalho de 1000 atividades em alguns segundos, enquanto é quase impossível carregar um fluxo de trabalho de algumas centenas de atividades com o designer do WF3.
Comparações de desempenho no nível do componente
Esta seção contém dados sobre comparações diretas entre atividades individuais em fluxos de trabalho WF3 e WF4. Áreas-chave, como persistência, têm um impacto mais profundo no desempenho do que os componentes de atividade individuais. No entanto, as melhorias de desempenho em componentes individuais no WF4 são importantes porque os componentes agora são rápidos o suficiente para serem comparados com a lógica de orquestração codificada à mão. Um exemplo do qual é abordado na próxima seção: "Cenário de composição de serviços".
Configuração do ambiente
A figura acima mostra a configuração do computador usada para medição de desempenho no nível do componente. Um único servidor e cinco clientes conectados em um adaptador de rede Ethernet de 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 provavelmente é a atividade 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. No WF4, não há um analógico direto para o WF3 CodeActivity que forneça a mesma funcionalidade. Observe que há uma CodeActivity classe base no WF4 que não está relacionada ao WF3 CodeActivity. Os autores de fluxo de trabalho são incentivados a criar atividades personalizadas e criar fluxos de trabalho somente XAML. Nos testes abaixo, uma atividade chamada Comment é usada em substituição a uma atividade vazia CodeActivity em fluxos de trabalho do WF4. O código na atividade Comment é o 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.
Atividade única
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.
Replicador comparado ao ParallelForEach
ReplicatorActivity no WF3 tem modos de execução sequenciais e paralelos. No modo sequencial, o desempenho da atividade é semelhante ao WhileActivity. O 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 este teste. O fluxo de trabalho do WF3 está à esquerda e o fluxo de trabalho WF4 está à direita.
Fluxo de trabalho sequencial com cinco atividades
Esse teste destina-se a mostrar o efeito de ter várias atividades executadas em sequência. Há cinco atividades na sequência.
Escopo da transação
O teste de escopo de transação difere ligeiramente dos outros testes, pois uma nova instância de fluxo de trabalho não é criada 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 execução de um lote de 50 iterações por meio do loop while é contada como uma única operação.
Remuneração
O fluxo de trabalho do WF3 tem uma única atividade compensatável chamada WorkScope. A atividade simplesmente implementa a ICompensatableActivity interface:
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 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 do corpo e a atividade do manipulador de compensação são implementações vazias:
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 fluxo de trabalho do WF3 está à esquerda e o fluxo de trabalho WF4 está à direita.
Resultados do teste de desempenho
Todos os testes são medidos em fluxos de trabalho por segundo, com exceção do teste de 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 Loja Online
Um dos pontos fortes do Windows Workflow Foundation é a capacidade de redigir processos usando vários serviços. Para este exemplo, há um serviço de loja online que orquestra duas chamadas de serviço para realizar uma compra. A primeira etapa é validar o pedido usando um Serviço de Validação de Pedidos. A segunda etapa é preencher o pedido usando um Serviço de Warehouse.
Os dois serviços de back-end, Serviço de Validação de Pedidos e Serviço de Warehouse, 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 é escrito como um serviço de fluxo de trabalho WCF em WF4. Recursos específicos do WF, como acompanhamento e persistência, são desativados para este teste.
Ambiente
As solicitações do cliente são feitas ao Serviço de Loja Online por meio de HTTP de vários computadores. Um único computador hospeda todos os três serviços. A camada de transporte entre o Serviço de Repositório Online e os serviços de back-end é 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. O pool de canais é um novo recurso disponível no WF4. Na parte do WCF deste teste, o agrupamento de canais não é fornecido automaticamente, então uma implementação codificada à mão de uma técnica simples de agrupamento foi usada no Serviço de Loja Online.
Desempenho
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 menor: 4.3% sem pool e 8.1% com pool. Também é importante observar que o pool de canais oferece muito pouco benefício ao usar HTTP.
Embora haja consumo adicional de recursos pelo runtime do WF4 em comparação com um serviço WCF codificado manualmente neste teste, isso pode ser considerado o pior cenário possível. Os dois serviços de back-end neste teste fazem muito pouco trabalho. Em um cenário real de ponta a ponta, esses serviços executariam operações mais caras, como chamadas de banco de dados, tornando o impacto no desempenho da camada de transporte menos importante. Isso além dos benefícios dos recursos disponíveis no WF4 torna o Workflow Foundation uma opção viável para a criação de serviços de orquestração.
Principais considerações sobre o desempenho
As áreas de funcionalidades nesta seção, com exceção da interoperabilidade, mudaram drasticamente entre o WF3 e o WF4. Isso afeta o design de aplicativos de fluxo de trabalho, bem como o desempenho.
Latência de ativação do 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 ser um fator de bloqueio. Esse caso de teste mede um host XOML do WF3 em relação a um host XAMLX WF4 em um cenário típico.
Configuração do ambiente
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. A correlação de contexto requer uma associação de contexto especial e usa um cabeçalho de contexto ou cookie para relacionar mensagens à instância de fluxo de trabalho correta. Ele tem um benefício de desempenho em que a ID de correlação está localizada no cabeçalho da mensagem para que o corpo da mensagem não precise ser analisado.
O serviço criará um novo fluxo de trabalho com a solicitação e enviará uma resposta imediata para que a medida da 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. O fluxo de trabalho do WF4 tem esta aparência:
A Receive atividade cria a instância de fluxo de trabalho. Um valor passado na mensagem recebida é ecoado na mensagem de resposta. Uma sequência após a resposta contém o restante do fluxo de trabalho. No caso acima, apenas uma atividade de comentário é mostrada. O número de atividades de comentário é alterado para simular a complexidade do fluxo de trabalho. Uma atividade de comentário é equivalente a um WF3 CodeActivity que não executa nenhum 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:
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 do fluxo de trabalho faz muito pouca diferença no caso WF4, mas tem uma progressão linear no caso WF3.
Taxa de transferência de correlação
O WF4 apresenta um novo recurso de correlação baseado em conteúdo. O WF3 forneceu apenas correlação baseada em contexto. A correlação baseada em contexto só poderia ser feita em associações de canal WCF específicas. A ID do fluxo de trabalho é inserida no cabeçalho da mensagem ao 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.
A correlação baseada em contexto tem uma vantagem de desempenho em que a chave de correlação está localizada no cabeçalho da mensagem. A chave pode ser lido de mensagem sem de- serialização/mensagem- copiar. Na correlação baseada em conteúdo, a chave de correlação é armazenada no corpo da mensagem. Uma expressão XPath é usada para localizar a chave. O custo desse processamento extra depende do tamanho da mensagem, da profundidade da chave no corpo e do número de chaves. Esse teste compara a correlação baseada em contexto e conteúdo e também mostra a degradação do desempenho ao usar várias chaves.
Configuração do ambiente
Configuração de teste
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. A correlação ocorre em dois locais: CreateOrder e CompleteOrder.
Resultados do teste
Este grafo mostra uma diminuição no desempenho à medida que o número de chaves usadas na correlação baseada em conteúdo aumenta. A similaridade nas curvas entre TCP e HTTP indica a sobrecarga associada a esses protocolos.
Correlação com persistência
Com um fluxo de trabalho persistente, a pressão da CPU da correlação baseada em conteúdo é transferida do ambiente de execução do fluxo de trabalho para o banco de dados de SQL. Os procedimentos armazenados no provedor de persistência do SQL fazem o trabalho de correspondência das chaves para localizar o fluxo de trabalho apropriado.
A correlação baseada em contexto ainda é mais rápida do que a correlação baseada em conteúdo. No entanto, a diferença é menos acentuada, pois a persistência tem mais impacto no desempenho do que na correlação.
Capacidade de processamento de fluxo de trabalho complexo
A complexidade de um fluxo de trabalho não é medida apenas 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. Esse teste compara a taxa de transferência entre o WF3 e o WF4 ao executar fluxos de trabalho complexos.
Configuração de teste
Esses testes foram executados em um computador Intel Xeon X5355 @ 2.66GHz 4 vias com 4 GB de RAM executando o Windows Server 2008 x64. O código de teste é executado em um único processo com um segmento pelo núcleo para atingir o uso da CPU 100%.
Os 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 de fluxograma se assemelha ao fluxograma principal. Pode ser útil pensar em um fractal ao imaginar esse fluxo de trabalho, em que a profundidade é limitada aos parâmetros do teste.
O número de atividades em um determinado teste é determinado pela profundidade e pelo número de atividades por sequência. A equação a seguir calcula o número de atividades no teste do WF4:
A contagem de atividades do teste do WF3 pode ser computada com uma equação ligeiramente diferente devido a uma sequência extra:
Onde d é a profundidade e um é o número de atividades por sequência. A lógica por trás dessas equações é que a primeira constante, multiplicada por a, é o número de sequências e a segunda constante é o número estático de atividades no nível atual. Há três atividades filhos do fluxograma em cada fluxograma. No nível inferior da profundidade, esses fluxogramas estão vazios, mas nos 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:
O número de atividades na definição de fluxo de trabalho aumenta acentuadamente com cada nível de profundidade. Mas apenas um caminho por ponto de decisão é executado em uma determinada instância de fluxo de trabalho, portanto, apenas um pequeno subconjunto das atividades reais é executado.
Um fluxo de trabalho equivalente foi criado para o 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 do fluxo de trabalho é mostrado abaixo.
Para exercitar aninhamento em casos, extremos outro fluxo de trabalho que seja parte dos usos 100 deste teste tivesse sequências. Na sequência mais interna há um único Comment ou CodeActivity.
O acompanhamento e a persistência não são utilizados como parte deste teste.
Resultados do teste
Mesmo com fluxos de trabalho complexos com muita profundidade e um alto número de atividades, os resultados de desempenho são consistentes com outros números de taxa de transferência mostrados anteriormente neste artigo. A taxa de transferência do WF4 é várias ordens de magnitude mais rápida e deve ser comparada em uma escala logarítmica.
Memória
A sobrecarga de memória do Windows Workflow Foundation é medida em duas áreas-chave: complexidade do fluxo de trabalho e número de definições de fluxo de trabalho. As medidas de memória foram feitas em uma estação de trabalho do Windows 7 de 64 bits. 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 de complexidade do fluxo de trabalho
O teste de complexidade do fluxo de trabalho mede a diferença do conjunto de trabalho com base na complexidade do fluxo de trabalho. Além dos fluxos de trabalho complexos usados na seção anterior, novas variações são adicionadas para abranger dois casos básicos: um fluxo de trabalho de atividade única e uma sequência com 1000 atividades. Para esses testes, os fluxos de trabalho são inicializados e executados para 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 registrados são a média dessas três execuções.
Os dois novos testes básicos têm fluxos de trabalho semelhantes aos mostrados abaixo:
No fluxo de trabalho do WF3 mostrado acima, atividades vazias 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.
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 mais significativo na memória vem 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.
Teste de várias definições de fluxo de trabalho
A medição da memória por definição de fluxo de trabalho é dividida em dois testes diferentes devido às opções disponíveis para hospedar fluxos de trabalho no WF3 e no WF4. Os testes são executados de uma maneira diferente do teste de complexidade do fluxo de trabalho, pois um determinado fluxo de trabalho é instânciado e executado apenas uma vez por definição. Isso ocorre porque a definição de fluxo de trabalho e seu host permanecem na memória durante o tempo de vida do AppDomain. A memória usada pela execução de uma determinada instância de fluxo de trabalho deve ser limpa durante a coleta de lixo. As diretrizes de migração do 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.
A criação de muitas definições de fluxo de trabalho para um teste de definição de fluxo de trabalho pode ser feita de várias maneiras. Por exemplo, é possível usar a geração de código para criar um conjunto de 1.000 fluxos de trabalho idênticos, exceto no nome e salvar cada um desses fluxos de trabalho em arquivos separados. Essa abordagem foi feita para o teste hospedado no console. No WF3, a WorkflowRuntime classe foi usada para executar as definições de fluxo de trabalho. O WF4 pode usar WorkflowApplication para criar uma única instância de fluxo de trabalho ou usar WorkflowInvoker diretamente para executar a atividade como se fosse uma chamada de método. WorkflowApplication é um host de uma única instância de fluxo de trabalho e tem maior paridade de recursos com WorkflowRuntime, por isso foi usado neste teste.
Ao hospedar fluxos de trabalho no IIS, é possível usar um VirtualPathProvider para criar um novo WorkflowServiceHost em vez de gerar todos os arquivos XAMLX ou XOML. Ele 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 1000 arquivos físicos.
As definições de fluxo de trabalho usadas no teste de console eram 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. O caso hospedado pelo IIS usou fluxos de trabalho que começam a receber uma mensagem e terminam ao 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:
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:
| Opções de hospedagem | Delta do conjunto de trabalho WF3 | Delta do conjunto de trabalho WF4 |
|---|---|---|
| Fluxos de trabalho hospedados do aplicativo de console | 18 MB | 9 MB |
| Serviços de fluxo de trabalho hospedados do IIS | 446 MB | 364 MB |
Hospedar definições de fluxo de trabalho no IIS consome muito mais memória devido aos WorkflowServiceHost, artefatos de serviço WCF detalhados e à lógica de processamento de mensagens associada ao host.
Para hospedagem de console no WF3, os fluxos de trabalho foram implementados no código em vez de XOML. No WF4, o padrão é usar XAML. O XAML é armazenado como um recurso inserido no assembly e compilado durante o runtime para fornecer a implementação do fluxo de trabalho. Há alguma sobrecarga associada a esse processo. Para fazer uma comparação justa entre o WF3 e o WF4, fluxos de trabalho codificados foram usados em vez de XAML. Um exemplo de um dos fluxos de trabalho do 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. O mesmo conselho para todos os programas gerenciados ainda se aplica. Em ambientes hospedados pelo IIS, o WorkflowServiceHost objeto criado para uma definição de fluxo de trabalho permanece na memória até que o pool de aplicativos seja 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
O WF3 e o WF4 são fornecidos com um provedor de persistência sql. O provedor de persistência do WF3 SQL é uma implementação simples que serializa a instância de fluxo de trabalho e a armazena em um blob. Por esse motivo, o desempenho desse provedor depende muito do tamanho da instância do fluxo de trabalho. No WF3, o tamanho da instância pode aumentar por muitos motivos, como é discutido anteriormente neste artigo. Muitos clientes optam por não usar o provedor de persistência de SQL padrão porque armazenar uma instância serializada em um banco de dados não oferece visibilidade do estado do fluxo de trabalho. Para encontrar um fluxo de trabalho específico sem saber a ID do fluxo de trabalho, seria necessário desserializar cada instância persistente e examinar o conteúdo. Muitos desenvolvedores preferem escrever seus próprios provedores de persistência para superar esse obstáculo.
O provedor de persistência do WF4 SQL tentou resolver algumas dessas preocupações. As tabelas de persistência expõem determinadas informações, como os favoritos ativos e as propriedades promovíveis. O novo recurso de correlação baseado em conteúdo no WF4 não teria um bom desempenho usando a abordagem de persistência do WF3 SQL, o que tem impulsionado alguma alteração na organização da instância de fluxo de trabalho persistente. Isso torna o trabalho do provedor de persistência mais complexo e coloca um estresse extra no banco de dados.
Configuração do ambiente
Configuração de teste
Mesmo com um conjunto de recursos aprimorado e melhor manipulação de simultaneidade, o provedor de persistência do SQL no WF4 é mais rápido que o provedor no WF3. Para mostrar isso, dois fluxos de trabalho que executam essencialmente as mesmas operações no WF3 e no WF4 são comparados abaixo.
Os dois fluxos de trabalho são criados por uma mensagem recebida. Depois de enviar uma resposta inicial, o fluxo de trabalho é mantido. No caso do WF3, um elemento vazio TransactionScopeActivity é usado para começar o processo de 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
Quando o transporte entre o cliente e a camada intermediária é HTTP, a persistência no WF4 mostra uma melhoria de 2,6 vezes. O transporte TCP aumenta esse fator para 3,0 vezes. Em todos os casos, a utilização da CPU na camada intermediária é de 98% ou superior. O motivo pelo qual a taxa de transferência do WF4 é maior é por causa do tempo de execução do fluxo de trabalho mais rápido. O tamanho da instância serializada é baixo para ambos os casos e não é um elemento importante contribuinte nessa situação.
Os fluxos de trabalho WF3 e WF4 neste teste usam uma atividade para indicar explicitamente quando a persistência deve ocorrer. Isso tem o benefício de persistir o fluxo de trabalho sem descarregá-lo. No WF3, também é possível persistir usando o TimeToUnload recurso, mas isso descarrega a instância de fluxo de trabalho da memória. Se um desenvolvedor que usa o WF3 quiser garantir que um fluxo de trabalho persista em determinados pontos, ele precisará alterar a definição do fluxo de trabalho ou pagar o custo para descarregar e recarregar a instância do fluxo de trabalho. Um novo recurso no WF4 possibilita persistir sem descarregar: TimeToPersist. Esse recurso permite que a instância de fluxo de trabalho seja mantida em ociosidade, mas permaneça na memória até que o TimeToUnload limite seja atingido ou a execução seja retomada.
Observe que o provedor de persistência do WF4 SQL executa mais trabalho na camada de banco de dados. O banco de dados SQL pode se tornar um gargalo, portanto, é importante monitorar o uso da CPU e do disco lá. Certifique-se de incluir os seguintes contadores de desempenho do banco de dados SQL ao testar aplicativos de fluxo de trabalho de teste de desempenho:
Tempo de leitura de PhysicalDisk \ %Disk
PhysicalDisk \ % de tempo de disco
PhysicalDisk\% Tempo de Gravação do Disco
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 acompanhamento de fluxo de trabalho pode ser usado para acompanhar o progresso de um fluxo de trabalho. As informações incluídas nos eventos de acompanhamento são determinadas por um perfil de acompanhamento. Quanto mais complexo for o perfil de acompanhamento, mais caro será o acompanhamento.
WF3 fornecido com um serviço de acompanhamento baseado em SQL. Esse serviço pode trabalhar nos modos processados em lotes e não processados em lotes. No modo não em lotes, os eventos de acompanhamento são gravados diretamente no banco de dados. No modo em lote, os eventos de rastreamento são coletados no mesmo lote que o estado da instância do fluxo de trabalho. O modo em lote tem o melhor desempenho para a maior variedade de designs 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 normalmente ocorre em loops e a melhor maneira de evitar esse cenário é criar loops grandes para conter um ponto de persistência. A introdução de um ponto de persistência em um loop também pode afetar negativamente o desempenho, portanto, é importante medir os custos de cada um e obter um equilíbrio.
O WF4 não é fornecido com um serviço de acompanhamento de SQL. Gravar informações de rastreamento em um banco de dados SQL pode ser realizado de forma mais eficiente a partir de um servidor de aplicações, em vez de integrado ao .NET Framework. Portanto, o acompanhamento do SQL agora é tratado pelo AppFabric. O provedor pronto para uso de rastreamento em WF4 é baseado no rastreamento de evento para o Windows (ETW).
O ETW é um sistema de eventos de baixa latência e nível de kernel integrado ao Windows. Ele usa um modelo de provedor/consumidor que permite incorrer na penalidade para o rastreamento de eventos apenas quando realmente há um consumidor. Além de eventos de kernel, como processador, disco, memória e uso de rede, muitos aplicativos também aproveitam o ETW. Os eventos ETW são mais poderosos do que os contadores de desempenho em que os eventos podem ser personalizados para o aplicativo. Um evento pode conter texto, como uma ID de fluxo de trabalho ou uma mensagem informativa. Além disso, os eventos são categorizados com máscaras de bits para que o consumo de um determinado subconjunto de eventos tenha menos impacto no desempenho do que capturar todos os eventos.
Os benefícios para a abordagem de usar o ETW para acompanhamento em vez de SQL incluem:
A coleção de eventos de rastreamento pode ser separada para outro processo. Isso proporciona maior flexibilidade na forma como os eventos são registrados.
Os eventos de acompanhamento de ETW são facilmente combinados com os eventos ETW do WCF ou outros provedores de 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 ETW poderão ser perdidos se o sistema estiver sob intensa pressão de recursos. O processamento de eventos não se destina a bloquear a execução normal do programa e, portanto, não é garantido que todos os eventos ETW serão transmitidos para seus assinantes. Isso torna o rastreamento do ETW ótimo para monitoramento de saúde, mas não é adequado para auditoria.
Embora o WF4 não tenha um provedor de acompanhamento de SQL, o AppFabric tem. A abordagem de acompanhamento de SQL do AppFabric é assinar eventos ETW com um Serviço Windows que agrupa os eventos e os grava em uma tabela SQL desenhada para permitir inserções rápidas. Um trabalho separado drena os dados dessa tabela e os reforma em tabelas de relatórios que podem ser exibidas no painel do AppFabric. Isso significa que um lote de eventos de rastreamento é tratado independentemente do fluxo de trabalho do qual ele veio e, portanto, não precisa aguardar um ponto de persistência antes de ser registrado.
Eventos ETW podem ser gravados com ferramentas como logman ou xperf. O arquivo ETL compacto pode ser exibido com uma ferramenta como xperfview ou convertida em um formato mais legível, como XML, com tracerpt. No WF3, a única opção para obter eventos de acompanhamento sem um banco de dados SQL é criar um serviço de acompanhamento personalizado. Para obter mais informações sobre o ETW, consulte os Serviços WCF e o Rastreamento de Eventos para Windows e Rastreamento de Eventos – aplicativos do Windows.
Habilitar o acompanhamento de fluxo de trabalho afetará o desempenho em diferentes graus. O parâmetro de comparação a seguir usa a ferramenta logman para consumir os eventos de acompanhamento do ETW e registrá-los em um arquivo ETL. O custo do acompanhamento do SQL no AppFabric não está no escopo deste artigo. O perfil de acompanhamento básico, também usado no AppFabric, é mostrado neste parâmetro de comparação. Também está incluído o custo de acompanhar apenas eventos de monitoramento de saúde. Esses eventos são úteis para solucionar problemas e determinar a taxa de transferência média do sistema.
Configuração do ambiente
Resultados do teste
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 facilitar a transição para o WF4 é usar a atividade interoperabilidade, que pode executar atividades do WF3 de dentro de um fluxo de trabalho WF4. É recomendável que a Interop atividade 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
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 de desempenho notável ao usar o Interop em vez do uso direto do WF3. No entanto, quando comparado com as atividades do WF4, o aumento é insignificante.
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. Os números de latência também são significativamente melhores. 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 aumentou em um fator de 2,5 a 3,0. O monitoramento de integridade por meio do acompanhamento de fluxo de trabalho agora tem muito pouca sobrecarga. Um conjunto abrangente de guias de migração está disponível para aqueles que estão considerando a migração do WF3 para o WF4. Tudo isso deve tornar o WF4 uma opção atraente para escrever aplicativos complexos.