Artigo: 821268 - Última revisão: sexta-feira, 16 de Março de 2007 - Revisão: 7.4

Problemas de contenção, desempenho fraco e bloqueios quando efectua pedidos de serviços Web a partir de aplicações ASP.NET

Dica do SistemaEste artigo aplica-se a um sistema operativo diferente do que está a utilizar. Foi desactivado o conteúdo do artigo, que pode não ser relevante para si.

Nesta página

Expandir tudo | Reduzir tudo

Sintomas

Quando efectua chamadas para serviços Web XML a partir de uma aplicação ASP.NET, poderá detectar problemas de contenção, desempenho fraco e bloqueios. Os clientes podem reportar que os pedidos deixaram de responder (ou "bloquearam") ou demoraram muito tempo a serem executados. Se suspeitar de um bloqueio, poderá reciclar o processo de trabalho. Poderá receber as seguintes mensagens no registo de eventos de aplicações.
  • Se estiver a utilizar o Microsoft IIS 5.0 (Serviços de informação Internet - Internet Information Services), receberá as seguintes mensagens no registo de eventos de aplicações:

       Tipo de evento:     Erro
       Origem do evento:   ASP.NET 1.0.3705.0
       Categoria do evento: Nenhuma 
       ID do evento:       1003
       Data:           5/4/2003
       Hora:           6:18:23 PM
       Utilizador:           N/D
       Computador:       <Nomedocomputador>
       Descrição:
          aspnet_wp.exe  (PID: <xxx>) was recycled because it was suspected to be in a deadlocked state.
          It did not send any responses for pending requests in the last 180 seconds.

  • Se estiver a utilizar o IIS 6.0, recebe as seguintes mensagens no registo de eventos de aplicações:

       Tipo de evento:     Aviso
       Origem do evento:   W3SVC-WP
       Categoria do evento: Nenhuma 
       ID do evento:       2262
       Data:           5/4/2003
       Hora:           1:02:33 PM
       Utilizador:           N/D
       Computador:       <Nomedocomputador>
       Descrição:
          O ISAPI 'C:\Windows\Microsoft.net\Framework\v.1.1.4322\aspnet_isapi.dll' comunicou estar
          danificado devido à seguinte razão: 'Bloqueio total detectado'.

  • Se estiver a utilizar o IIS 6.0, receberá as seguintes mensagens no registo de eventos do sistema:

       Tipo de evento:     Aviso 
       Origem do evento:   W3SVC
       Categoria do evento: Nenhuma 
       ID do evento:       1013
       Data:           5/4/2003
       Hora:           1:03:47 PM
       Utilizador:           N/D 
       Computador:       <Nomedocomputador>
       Descrição:
          Um processo que fornecia serviços ao agrupamento de aplicações 'DefaultAppPool' excedeu os limites de tempo durante o encerramento.
          ID do processo '<xxxx>'.

Também poderá receber a seguinte mensagem de erro de excepção quando efectua uma chamada para o método HttpWebRequest.GetResponse:
?System.InvalidOperationException: There were not enough free threads in the ThreadPool object to complete the operation.?
Também poderá receber a seguinte mensagem de erro de excepção no browser:
?HttpException (0x80004005): Request timed out.?
Nota: este artigo aplica-se às aplicações que efectuam pedidos HttpWebRequest directamente.

Causa

Este problema poderá ocorrer porque o ASP.NET limita o número de threads de trabalho e de threads de porta de conclusão que poderão ser utilizados por uma chamada para executar pedidos.

Normalmente, uma chamada para um serviço Web utiliza um thread de trabalho para executar o código que envia o pedido e um thread de porta de conclusão para receber a chamada de retorno do serviço Web. No entanto, se o pedido for redireccionado ou necessitar de autenticação, a chamada poderá utilizar até dois threads de trabalho e dois threads de porta de conclusão. Por conseguinte, poderá esgotar o ThreadPool gerido quando ocorrerem múltiplas chamadas de serviços Web ao mesmo tempo.

Por exemplo, suponha que o ThreadPool está limitado a 10 threads de trabalho e todos os 10 threads de trabalho estão actualmente a executar código que aguarda a execução de uma chamada de retorno. A chamada de retorno poderá nem ser executada porque os itens de trabalho em fila de espera para o ThreadPool são bloqueados até que um thread seja disponibilizado.

Outra origem possível de contenção é o parâmetro maxconnection utilizado pelo espaço de nomes System.Net para limitar o número de ligações. Geralmente, este limite funciona como previsto. No entanto, se muitas aplicações tentarem efectuar muitos pedidos para um único endereço IP ao mesmo tempo, os threads poderão ter de aguardar por uma ligação disponível.

Resolução

Para resolver estes problemas, pode ajustar os seguintes parâmetros no ficheiro Machine.config, conforme a sua situação:
  • maxWorkerThreads
  • minWorkerThreads
  • maxIoThreads
  • minFreeThreads
  • minLocalRequestFreeThreads
  • maxconnection
  • executionTimeout
Para resolver estes problemas com êxito, proceda da seguinte forma:
  • Limite o número de pedidos ASP.NET que podem ser executados ao mesmo tempo para aproximadamente 12 por CPU.
  • Permita que as chamadas de retorno de serviços Web utilizem threads livremente no ThreadPool.
  • Seleccione um valor adequado para o parâmetro maxconnections. Baseie a sua selecção no número de endereços IP e AppDomains utilizados.
Nota: a recomendação para limitar o número de pedidos ASP.NET em 12 por CPU é um pouco arbitrária. No entanto, na maioria das aplicações este limite funcionou correctamente.

maxWorkerThreads e maxIoThreads

O ASP.NET utiliza as seguintes duas definições de configuração para limitar o número máximo de threads de trabalho e de threads de conclusão utilizados:
<processModel maxWorkerThreads="20" maxIoThreads="20">
O parâmetro maxWorkerThreads e o parâmetro maxIoThreads são multiplicados implicitamente pelo número de CPUs. Por exemplo, se tiver dois processadores, o número máximo de threads de trabalho é o seguinte:
2*maxWorkerThreads

minFreeThreads e minLocalRequestFreeThreads

O ASP.NET também contém as seguintes definições de configuração que determinam quantos threads de trabalho e threads de portas de conclusão têm de estar disponíveis para iniciar um pedido remoto ou um pedido local:
<httpRuntime minFreeThreads="8" minLocalRequestFreeThreads="8">
Se não existirem threads suficientes disponíveis, o pedido é colocado em fila de espera até que sejam disponibilizados threads suficientes para efectuarem o pedido. Por conseguinte, o ASP.NET não executará mais do que o seguinte número de pedidos ao mesmo tempo:
(maxWorkerThreads*número de CPUs)-minFreeThreads
Nota: os parâmetros minFreeThreads e minLocalRequestFreeThreads não são multiplicados implicitamente pelo número de CPUs.

minWorkerThreads

Como o ASP.NET 1.0 Service Pack 3 e o ASP.NET 1.1, o ASP.NET também contém a seguinte definição de configuração que determina quantos threads de trabalho poderão ser disponibilizados imediatamente para executar um pedido remoto.
<processModel minWorkerThreads="1">
Os threads que são controlados por esta definição podem ser criados mais rapidamente do que os threads de trabalho que são criados a partir de funcionalidades predefinidas de "ajuste de threads" de CLR. Esta definição permite que o ASP.NET execute pedidos que subitamente poderão estar a preencher a fila de pedidos ASP.NET em espera devido a um abrandamento num servidor back end, um súbito aumento de pedidos do lado do cliente, ou uma situação semelhante que poderá causar um aumento inesperado do número de pedidos em fila de espera. O valor predefinido do parâmetro minWorkerThreads é 1. A Microsoft recomenda que defina o valor do parâmetro minWorkerThreads com o seguinte valor.
minWorkerThreads = maxWorkerThreads / 2
Por predefinição, o parâmetro minWorkerThreads não existe no ficheiro Web.config nem no ficheiro Machine.config. Esta definição é multiplicada implicitamente pelo número de CPUs.

maxconnection

O parâmetro maxconnection determina quantas ligações podem ser efectuadas para um endereço IP específico. O parâmetro é apresentado da seguinte forma:
<connectionManagement>
    <add address="*" maxconnection="2">
    <add address="65.53.32.230" maxconnection="12">
</connectionManagement>
As definições para os parâmetros abordados anteriormente neste artigo encontram-se todas em processamento. No entanto, a definição do parâmetro maxconnection aplica-se ao nível de AppDomain. Por predefinição, uma vez que esta definição se aplica ao nível de AppDomain, pode criar duas ligações no máximo para um endereço IP específico a partir de cada AppDomain no processo.

executionTimeout

O ASP.NET utiliza a seguinte definição de configuração para limitar o tempo de execução do pedido:
<httpRuntime executionTimeout="90"/>
Também pode definir este limite utilizando a propriedade Server.ScriptTimeout.

Nota: se aumentar o valor do parâmetro executionTimeout, também poderá necessitar de modificar a definição do parâmetro processModel responseDeadlockInterval.

Recomendações

As definições recomendadas nesta secção poderão não funcionar em todas as aplicações. No entanto, as informações adicionais que se seguem poderão ajudá-lo a efectuar os ajustes adequados.

Se estiver a efectuar uma chamada de serviço Web para um único endereço IP a partir de cada página ASPX, a Microsoft recomenda que utilize as seguintes definições de configuração:
  • Defina os valores do parâmetro maxWorkerThreads e do parâmetro maxIoThreads como 100.
  • Defina o valor do parâmetro maxconnection como 12*N (em que N corresponde ao número de CPUs existentes).
  • Defina os valores do parâmetro minFreeThreads como 88*N e do parâmetro minLocalRequestFreeThreads como 76*N.
  • Defina o valor de minWorkerThreads como 50. Lembre-se que, minWorkerThreads não se encontra no ficheiro de configuração por predefinição. Tem de adicioná-lo.
Algumas destas recomendações implicam uma simples fórmula que envolve o número de CPUs de um servidor. A variável que representa o número de CPUs nas fórmulas é N. Nestas definições, se tiver a hyperthreading activada, terá de utilizar o número de CPUs lógicas em vez de o número de CPUs físicas. Por exemplo, se tiver um servidor com quatro processadores com a hyperthreading activada, o valor de N nas fórmulas será 8 em vez de 4.

Nota: quando utiliza esta configuração, pode executar no máximo 12 pedidos ASP.NET por CPU ao mesmo tempo porque 100-88=12. Por conseguinte, pelo menos 88*N threads de trabalho e 88*N threads de porta de conclusão estão disponíveis para outras utilizações (como para chamadas de retorno de serviços Web).

Por exemplo, tem um servidor com quatro processadores e hyperthreading activada. Com base nestas fórmulas, utilizará os seguintes valores para as definições de configuração mencionadas neste artigo.
<processModel maxWorkerThreads="100" maxIoThreads="100" minWorkerThreads="50">
<httpRuntime minFreeThreads="704" minLocalRequestFreeThreads="608"> 
<connectionManagement>
	<add address="[ProvideIPHere]" maxconnection="96"/>
</connectionManagement>

Do mesmo modo, quando utiliza esta configuração, existem 12 ligações disponíveis para CPU por endereço IP para cada AppDomain. Por conseguinte, no seguinte cenário, ocorre muito pouca contenção quando os pedidos aguardam por ligações e o ThreadPool não é totalmente utilizado:
  • A Web hospeda apenas uma aplicação (AppDomain).
  • Cada pedido para uma página ASPX corresponde a um pedido de serviço Web.
  • Todos os pedidos são para o mesmo endereço IP.
No entanto, quando utiliza esta configuração, os cenários que envolvem uma das seguintes situações provavelmente utilizarão demasiadas ligações:
  • Os pedidos são para múltiplos endereços IP.
  • Os pedidos são redireccionados (código de estado 302).
  • Os pedidos requerem autenticação.
  • Os pedidos são efectuados a partir de múltiplos AppDomains.
Nestes cenários, deve utilizar um valor inferior para o parâmetro maxconnection e valores mais elevados para os parâmetros minFreeThreads e minLocalRequestFreeThreads.

Ponto Da Situação

Este comportamento ocorre por predefinição.

Referências

Para obter mais informações, visite o seguinte Web site da MSDN (Microsoft Developer Network):
http://msdn2.microsoft.com/en-us/library/ms998549.aspx (http://msdn2.microsoft.com/en-us/library/ms998549.aspx)

A informação contida neste artigo aplica-se a:
  • Microsoft ASP.NET 1.1
  • Microsoft ASP.NET 1.0
Palavras-chave: 
kbprb KB821268
Retired KB ArticleExclusão de Responsabilidade para Conteúdo sem Suporte na KB
Este artigo foi escrito sobre produtos para os quais a Microsoft já não fornece suporte. Por conseguinte, este artigo é oferecido "tal como está" e deixará de ser actualizado.