92 votes

Qu'est-ce qui limite le nombre de connexions simultanées que mon application ASP.NET peut établir avec un service Web ?

J'ai une application ASP.NET 4.0 fonctionnant sous IIS 7.5 sur une machine Windows Server 2008 R2 Enterprise 64 bits avec beaucoup de RAM, de CPU, de disque, etc.

À chaque demande Web, l'application ASP.NET établit une connexion avec un service Web dorsal (via des sockets bruts), qui fonctionne sur la même machine.

Problème : Il semble que quelque chose limite le nombre de connexions simultanées au service web dorsal. De façon suspecte, le nombre de connexions simultanées plafonne à 16.

J'ai trouvé cet article clé de Microsoft expliquant comment modifier les paramètres d'IIS afin d'accommoder les applications ASP.NET qui font beaucoup de demandes de services Web : http://support.microsoft.com/?id=821268#tocHeadRef

J'ai suivi les recommandations de l'article, mais toujours pas de chance. Le paramètre qui est particulièrement intéressant est le maxconnection que j'ai même fait passer à 999.

Une idée de ce que sinon pourrait restreindre les connexions ?

Note : Lorsque j'élimine IIS du mélange et que les clients se connectent directement au service web dorsal, celui-ci ouvre volontiers autant de connexions que nécessaire, ce qui me permet d'affirmer que le backend n'est pas le goulot d'étranglement. Cela doit être quelque chose dans IIS/ASP.NET-land.

Voici la section pertinente de la machine.config qui, j'en suis sûr, est lu par l'application (vérifié avec 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>

106voto

BenSwayne Points 10621

La plupart des réponses fournies ici concernent le nombre de demandes entrantes à votre service web backend, et non le nombre de demandes sortantes que vous pouvez faire depuis votre application ASP.net vers votre service backend.

Ce n'est pas votre service Web dorsal qui limite votre taux de demande, mais le nombre de connexions ouvertes que votre application appelante est prête à établir vers le même point de terminaison (même URL).

Vous pouvez supprimer cette limitation en ajoutant la section de configuration suivante à votre fichier machine.config :

<configuration>
  <system.net>
    <connectionManagement>
      <add address="*" maxconnection="65535"/>
    </connectionManagement>
  </system.net>
</configuration>

Vous pouvez bien sûr choisir un nombre plus raisonnable si vous le souhaitez, par exemple 50 ou 100 connexions simultanées. Mais le chiffre ci-dessus vous permettra d'atteindre le maximum. Vous pouvez également spécifier une adresse spécifique pour la règle de limite d'ouverture ci-dessus plutôt que le '*' qui indique toutes les adresses.

Documentation MSDN pour System.Net.connectionManagement

Une autre excellente ressource pour comprendre ConnectManagement en .NET

J'espère que cela résoudra votre problème !

EDITAR: Oups, je vois que vous avez la gestion des connexions mentionnée dans votre code ci-dessus. Je vais laisser mes informations ci-dessus car elles sont pertinentes pour les futurs demandeurs ayant le même problème. Cependant, veuillez noter il y a actuellement 4 fichiers machine.config différents sur la plupart des serveurs à jour !

Il existe un .NET Framework v2 fonctionnant à la fois sous 32 et 64 bits, ainsi qu'un .NET Framework v4 fonctionnant également sous 32 et 64 bits. En fonction des paramètres choisis pour votre pool d'applications, vous pouvez utiliser l'un de ces 4 fichiers machine.config différents ! Veuillez vérifier les 4 fichiers machine.config généralement situés ici :

  • C:\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG
  • C:\Windows\Microsoft.NET\Framework64\v2.0.50727\CONFIG
  • C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config
  • C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config

8voto

Sebastian Hek Points 11

Je réalise que la question peut être assez ancienne, mais vous dites que le backend fonctionne sur le même serveur. Cela signifie qu'il fonctionne sur un port différent, probablement autre que le port 80 par défaut.

J'ai lu que lorsque vous utilisez l'élément de configuration "connectionManagement", vous devez spécifier le numéro de port s'il diffère du 80 par défaut.

LIEN : Le paramètre maxConnection peut ne pas fonctionner même si autoConfig = false en ASP.NET

Deuxièmement, si vous choisissez d'utiliser la configuration par défaut (address="*") étendue avec votre propre valeur spécifique au backend, vous pourriez envisager de mettre la valeur spécifique en premier ! Sinon, si une demande est faite, le * correspond d'abord et la valeur par défaut de 2 connexions est prise. Tout comme lorsque vous utilisez la section dans web.config.

LIEN : <remove> Élément pour connectionManagement (Paramètres réseau)

J'espère que cela aidera quelqu'un.

6voto

Ruben Points 8393

Serait-il possible que vous utilisiez un service web de référence basé sur WCF ? Par défaut, la référence ServiceThrottlingBehavior.MaxConcurrentCalls (en anglais) est de 16 ans.

Vous pouvez essayer de mettre à jour le comportement de référence de votre service. <serviceThrottling> élément

<serviceThrottling
    maxConcurrentCalls="999" 
    maxConcurrentSessions="999" 
    maxConcurrentInstances="999" />

(Notez que je recommanderais les paramètres ci-dessus.) Voir MSDN pour plus d'informations sur la manière de configurer un <behavior> élément.

3voto

Simon Mourier Points 49585

Avez-vous essayé de définir la valeur de l'attribut statique DefaultConnectionLimit de manière programmatique ?

Voici une bonne source d'information sur ce véritable mal de tête... Utilisation des threads ASP.NET sur IIS 7.5, IIS 7.0 et IIS 6.0 avec des mises à jour pour le framework 4.0.

2voto

Matthew Evans Points 1359

Voir la section "Enfilage" de cette page : http://msdn.microsoft.com/en-us/library/ff647786.aspx en conjonction avec la section "Connexions".

Avez-vous essayé d'augmenter l'attribut maxconnection de votre paramètre processModel ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X