Eu tenho um aplicativo ASP.NET 4.0 em execução no IIS 7.5 em uma máquina Windows Server 2008 R2 Enterprise de 64 bits com montes de RAM, CPU, disco, etc.
Com cada solicitação da Web, o aplicativo ASP.NET faz uma conexão com um serviço da Web de back-end (por meio de soquetes brutos), que está sendo executado na mesma máquina.
Problema: parece haver algo limitando o número de conexões simultâneas ao serviço da web de back-end. Suspeito, o número de conexões simultâneas está chegando a 16.
Encontrei este artigo importante da Microsoft explicando como ajustar as configurações do IIS para acomodar aplicativos ASP.NET que fazem muitas solicitações de serviço da Web: http://support.microsoft.com/?id=821268#tocHeadRef
Segui as recomendações do artigo, mas ainda sem sorte. A configuração que é particularmente interessante é a maxconnection
configuração, que até aumentei para 999.
Alguma ideia do que mais poderia ser conexões de estrangulamento?
Observação: quando eu excluo o IIS da mistura e faço com que os clientes se conectem diretamente ao serviço da web de back-end, ele felizmente abrirá quantas conexões forem necessárias, portanto, tenho certeza de que o back-end não é o gargalo. Deve ser algo na área do IIS / ASP.NET.
Esta é a seção relevante do machine.config
que tenho certeza que está sendo lida pelo aplicativo (verificado com appcmd.exe
):
<system.web>
<processModel autoConfig="false" maxWorkerThreads="100" maxIoThreads="100" minWorkerThreads="50" />
<httpRuntime minFreeThreads="176" minLocalRequestFreeThreads="152"/>
<httpHandlers />
<membership>
<providers>
<add name="AspNetSqlMembershipProvider"
type="System.Web.Security.SqlMembershipProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="LocalSqlServer"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="true"
applicationName="/"
requiresUniqueEmail="false"
passwordFormat="Hashed"
maxInvalidPasswordAttempts="5"
minRequiredPasswordLength="7"
minRequiredNonalphanumericCharacters="1"
passwordAttemptWindow="10"
passwordStrengthRegularExpression="" />
</providers>
</membership>
<profile>
<providers>
<add name="AspNetSqlProfileProvider" connectionStringName="LocalSqlServer" applicationName="/"
type="System.Web.Profile.SqlProfileProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</providers>
</profile>
<roleManager>
<providers>
<add name="AspNetSqlRoleProvider" connectionStringName="LocalSqlServer" applicationName="/"
type="System.Web.Security.SqlRoleProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<add name="AspNetWindowsTokenRoleProvider" applicationName="/"
type="System.Web.Security.WindowsTokenRoleProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</providers>
</roleManager>
</system.web>
<system.net>
<connectionManagement>
<add address="*" maxconnection="999"/>
</connectionManagement>
</system.net>
fonte
Respostas:
A maioria das respostas fornecidas aqui aborda o número de solicitações de entrada para seu serviço da web de back-end, não o número de solicitações de saída que você pode fazer de seu aplicativo ASP.net para seu serviço de back-end.
Não é o seu serviço da web de back-end que está limitando sua taxa de solicitação, é o número de conexões abertas que seu aplicativo de chamada está disposto a estabelecer para o mesmo ponto de extremidade (mesma URL).
Você pode remover essa limitação adicionando a seguinte seção de configuração ao arquivo machine.config:
Você pode, é claro, escolher um número mais razoável se desejar, como 50 ou 100 conexões simultâneas. Mas o texto acima irá abri-lo no máximo. Você também pode especificar um endereço específico para a regra de limite de abertura acima, em vez do '*' que indica todos os endereços.
Documentação MSDN para System.Net.connectionManagement
Outro ótimo recurso para entender o ConnectManagement em .NET
Espero que isso resolva seu problema!
EDIT: Opa, vejo que você tem o gerenciamento de conexão mencionado em seu código acima. Vou deixar minhas informações acima, pois são relevantes para futuros inquiridores com o mesmo problema. No entanto, observe que atualmente existem 4 arquivos machine.config diferentes na maioria dos servidores atualizados!
Há o .NET Framework v2 rodando em 32 bits e 64 bits, bem como o .NET Framework v4 também rodando em 32 bits e 64 bits. Dependendo das configurações escolhidas para o pool de aplicativos, você pode usar qualquer um desses 4 arquivos machine.config diferentes! Verifique todos os 4 arquivos machine.config normalmente localizados aqui:
fonte
machine.config
(64 bits 4.0).Sei que a pergunta pode ser bastante antiga, mas você diz que o back-end está sendo executado no mesmo servidor. Isso significa em uma porta diferente, provavelmente diferente da porta 80 padrão.
Eu li que quando você usa o elemento de configuração "connectionManagement", você precisa especificar o número da porta se for diferente do padrão 80.
LINK: a configuração maxConnection pode não funcionar mesmo autoConfig = false no ASP.NET
Em segundo lugar, se você escolher usar a configuração padrão (endereço = "*") estendida com seu próprio valor específico de back-end, você pode considerar colocar o valor específico primeiro! Caso contrário, se uma solicitação for feita, o * corresponde primeiro e o padrão de 2 conexões é usado. Exatamente como quando você usa a seção em web.config.
LINK: Elemento <remove> para connectionManagement (configurações de rede)
Espero que ajude alguém.
fonte
É possível que você esteja usando uma referência de serviço da web baseada em WCF? Por padrão, ServiceThrottlingBehavior.MaxConcurrentCalls é 16.
Você pode tentar atualizar seu
<serviceThrottling>
elemento de comportamento de referência de serviço(Observe que eu recomendo as configurações acima.) Consulte MSDN para obter mais informações sobre como configurar um
<behavior>
elemento apropriado .fonte
TcpClient
(o serviço vende blobs binários personalizados, não WCF / SOAP ou similar). Essas opções de configuração parecem estar impactando puramente se você usarServiceHost
, nãoTcpClient
; estou esquecendo de algo?Você tentou definir o valor da propriedade estática DefaultConnectionLimit programaticamente?
Aqui está uma boa fonte de informações sobre essa verdadeira dor de cabeça ... Uso de thread ASP.NET no IIS 7.5, IIS 7.0 e IIS 6.0 , com atualizações para o framework 4.0.
fonte
Consulte a seção "Threading" desta página: http://msdn.microsoft.com/en-us/library/ff647786.aspx , em conjunto com a seção "Conexões".
Você já tentou aumentar o atributo maxconnection de sua configuração processModel?
fonte
maxconnection
atributo não se aplica a chamadas de serviço web locais . Neste caso particular o serviço web é local, mas temos o mesmo problema em outro ambiente onde o serviço não é local.minLocalRequestFreeThreads
- Este processo de trabalho usa essa configuração para enfileirar solicitações de localhost (onde um aplicativo da Web chama um serviço da Web no mesmo servidor ) se o número de threads disponíveis no pool de threads ficar abaixo desse número. Essa configuração é semelhante a minFreeThreads, mas se aplica apenas a solicitações que usam localhost .minLocalRequestFreeThreads
(veja minhamachine.config
pergunta.Se não estiver definido no serviço da web ou aplicativo ou servidor (apache ou IIS) que hospeda o consumível do serviço da web, você pode criar conexões infinitas até a falha
fonte
ao fazer o teste de desempenho, a medida que eu uso é RPS, ou seja, quantas solicitações por segundo o servidor pode atender com latência aceitável.
teoricamente, um servidor só pode executar tantas solicitações simultaneamente quanto o número de núcleos nele.
Não parece que o problema seja o modelo de threading do ASP.net, uma vez que pode servir potencialmente a milhares de rps. Parece que o problema pode ser seu aplicativo. Você está usando algum primitivo de sincronização?
também qual é a latência em seus serviços da web, eles são muito rápidos para responder (em microssegundos), se não, você pode querer considerar chamadas assíncronas, para que você não acabe bloqueando
Se isso não render nada, você pode querer criar um perfil de seu código usando o visual studio ou redgate profiler
fonte