web-dev-qa-db-fra.com

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 exécutée sur IIS 7.5 sur une machine Windows Server 2008 R2 Enterprise 64 bits avec des quantités de RAM, d'UC, de disque, etc.

Avec chaque requête Web, l'application ASP.NET établit une connexion avec un service Web principal (via des sockets bruts), qui s'exécute sur le même ordinateur.

Problème: Il semble y avoir quelque chose qui limite le nombre de connexions simultanées au service Web principal. De manière suspecte, le nombre de connexions simultanées est supérieur à 16.

J'ai trouvé cet article clé de Microsoft expliquant comment modifier les paramètres d'IIS pour prendre en charge les applications ASP.NET générant de nombreuses demandes de service 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 paramètre maxconnection que je suis même passé à 999.

Toute idée de ce que sinon pourrait être une limitation des connexions?

Remarque: Lorsque je coupe IIS) et que les clients se connectent directement au service Web principal, il ouvrirai volontiers le nombre de connexions dont j’ai besoin, je suis donc convaincu que l’arrière-plan n’est pas le goulot d’étranglement, mais bien quelque chose dans IIS/ASP.NET-land.

Voici la section pertinente de la machine.config dont l'application, j'en suis sûr, est en train de lire (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>
86
Rob Sobers

La plupart des réponses fournies ici concernent le nombre de demandes entrantes à votre service Web backend, pas le nombre de demandes sortantes que vous pouvez effectuer à partir de votre application ASP.net à votre service backend.

Ce n’est pas votre service Web principal qui limite le débit de votre demande ici, c’est le nombre de connexions ouvertes que votre application appelante est disposée à établir vers le même point de terminaison (même adresse 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 souhaitez 50 ou 100 connexions simultanées. Mais ce qui précède l’ouvrira jusqu’à max. 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

ne autre grande ressource pour comprendre ConnectManagement dans .NET

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

EDIT: Oups, je vois que vous avez la gestion de connexion mentionnée dans votre code ci-dessus. Je laisserai mes informations ci-dessus car elles sont pertinentes pour les futurs demandeurs avec le même problème. Cependant, veuillez noter qu'il existe actuellement 4 fichiers machine.config différents sur les serveurs les plus récents!

.NET Framework v2 fonctionne à la fois en 32 bits et 64 bits, ainsi que .NET Framework v4 également en 32 bits et 64 bits. Selon les paramètres que vous avez 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
98
BenSwayne

Je me rends compte que la question est peut-être un peu ancienne, mais vous dites que le backend tourne sur le même serveur. Cela signifie que sur un port différent, probablement autre que le port par défaut 80.

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 de celui par défaut 80.

LIEN: le paramètre maxConnection peut ne pas fonctionner même autoConfig = false dans ASP.NET

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

LINK: <remove> Element for connectionManagement (Paramètres réseau)

J'espère que ça aide quelqu'un.

7
Sebastian Hek

Serait-il possible que vous utilisiez une référence de service Web basée sur WCF? Par défaut, le ServiceThrottlingBehavior.MaxConcurrentCalls est 16.

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

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

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

5
Ruben

Avez-vous essayé de définir la valeur de la propriété statique DefaultConnectionLimit par programme?

Voici une bonne source d’informations sur ce véritable casse-tête ... Utilisation des threads ASP.NET sur IIS 7.5, IIS 7.0 et IIS 6.0 , avec mises à jour pour Framework 4.0.

3
Simon Mourier

Consultez la section "Threading" de cette page: http://msdn.Microsoft.com/en-us/library/ff647786.aspx , conjointement avec la section "Connexions".

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

2
Matthew Evans

tout en effectuant des tests de performances, la mesure utilisée est le nombre de requêtes par seconde, c’est-à-dire le nombre de requêtes par seconde que le serveur peut traiter avec une latence acceptable.

théoriquement, un serveur ne peut exécuter autant de requêtes simultanément que de cœurs.

Il ne semble pas que le problème vienne du modèle de thread ASP.net, car il peut potentiellement servir des milliers de RPS. Il semble que le problème pourrait être votre application. Utilisez-vous des primitives de synchronisation?

la latence de vos services Web est également très rapide (en quelques microsecondes), sinon, vous voudrez peut-être envisager les appels asynchrones pour ne pas bloquer.

Si cela ne vous empêche pas quelque chose, alors vous voudrez peut-être profiler votre code en utilisant Visual Studio ou Redgate Profiler

0
np-hard

S'il n'est pas défini dans le service Web, l'application ou le serveur (Apache ou IIS) hébergeant le consommable de service Web, vous pouvez créer un nombre infini de connexions jusqu'à l'échec.

0
Frank Tudor