30 votes

Amélioration des performances de HttpWebRequests multithread dans .NET

Je suis en train d'essayer de mesurer le débit d'un webservice.

Pour ce faire, j'ai écrit un petit outil qui envoie en permanence des demandes et lit les réponses d'un nombre de threads.

Le contenu de la boucle interne de chaque thread ressemble à ceci:

public void PerformRequest()
{
  WebRequest webRequest = WebRequest.Create(_uri);

  webRequest.ContentType = "application/ocsp-request";
  webRequest.Method = "POST";
  webRequest.Credentials = _credentials;
  webRequest.ContentLength = _request.Length;
  ((HttpWebRequest)webRequest).KeepAlive = false;

  using (Stream st = webRequest.GetRequestStream())
    st.Write(_request, 0, _request.Length);

  using (HttpWebResponse httpWebResponse = (HttpWebResponse)webRequest.GetResponse())
  using (Stream responseStream = httpWebResponse.GetResponseStream())
  using (BufferedStream bufferedStream = new BufferedStream(responseStream))
  using (BinaryReader reader = new BinaryReader(bufferedStream))
  {
    if (httpWebResponse.StatusCode != HttpStatusCode.OK)
      throw new WebException("Got response status code: " + httpWebResponse.StatusCode);

    byte[] response = reader.ReadBytes((int)httpWebResponse.ContentLength);
    httpWebResponse.Close();
  }      
}

Il semble fonctionner ok, sauf que quelque chose semble être un facteur limitant de l'outil. Si je exécuter deux instances de l'outil à chaque 40 fils, je reçois beaucoup plus de débit qu'une seule instance avec 80 fils.

J'ai trouvé le ServicePointManager.DefaultConnectionLimit bien, que j'ai mis à 10000 (et il ne fait aucune différence si je l'ai mis à partir de l'app.config comme suggéré par Jader Dias).

Existe-il d'autres paramètres .NET ou sur ma machine qui peuvent influencer la performance? (Je suis sous Vista, mais je vois le même problème sur Windows Server 2003).

Peut-être certaines restrictions sur le nombre de connexions d'un seul processus peut faire?

42voto

Jader Dias Points 23461

Vous devez définir le paramètre maxconnection dans le fichier app.config ou web.config:

 <?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.net>
    <connectionManagement>
      <add address="*" maxconnection="80"/>
    </connectionManagement>
  </system.net>
</configuration>
 

Les valeurs jusqu'à 100 fonctionnent très bien avec Windows XP.

Mise à jour: je viens de découvrir que la méthode ci-dessus est un autre moyen de définir System.Net.ServicePointManager.DefaultConnectionLimit

2voto

shaunf Points 323

2voto

shaunf Points 323

avez-vous essayé d'augmenter le nombre maximal de connexions dans les paramètres réseau?

http://msdn.microsoft.com/en-us/library/fb6y0fyc.aspx

1voto

Peter Oehlert Points 6351

Gardez à l'esprit du code multithread peut toujours provoquer des conflits sur les ressources partagées et même si vous n'êtes pas explicitement le partage de tout ce que vous pourriez être en utilisant des classes qui sont le partage de ressources sous les couvertures.

Si vous êtes vraiment obtenir de meilleures performances avec 2 40 thread exe de 1 80 thread exe puis vous aurez besoin pour commencer votre enquête avec des ressources partagées. Et si c'est le cas, le code que vous avez cité est bien moins intéressant que le code qui crée et gère les threads.

L'autre chose que j'avais à jeter, il y a, il existe plusieurs outils que vous pouvez obtenir qui va faire ce genre de chose pour vous d'une manière générique. Voir http://support.microsoft.com/kb/231282. Également inclus dans Visual Studio (je ne suis pas sûr de ce que sku) est une nouvelle génération d'application web tests de performance des outils. Et je suis sûr que si vous avez regardé, vous pouvez trouver certains non-MME des trucs aussi.

0voto

Dreamer Points 921

Il y a deux aspects importants w.r.t:

  1. Un aspect est comme suggéré par tous, le nombre de connexions TCP été utilisé par le client (généralement mieux si ces connexions sont conservées (garder vivant = true)) pour les détails, se référer à : http://msdn.microsoft.com/en-us/library/system.net.servicepoint.connectionlimit(v=vs. 110).aspx, Comment et où la connexion TCP a été créé en httpwebrequest, et comment est-il lié à servicepoint? , Pourquoi Système.Net.ServicePoint.ConnectionLimit utilise 7FFFFFFF' (Int32.MaxValue/2147483647) lorsqu'un client se connecte à un service sur 'localhost'? , Système.Net.ServicePointManager.DefaultConnectionLimit et .MaxServicePointIdleTime )

  2. Deuxième aspect est plutôt que l'utilisation de plusieurs nouveaux threads/ou de l'utilisation de threads de travail à faire travailler en parallèle à l'aide des appels synchrones (comme httpwebrequest.getrequeststream) dans l'extrait de code, embrassant async modèle complètement (par ex, commencer/endrequeststream, ou une nouvelle tâche de variations). De cette façon, CPU sera toujours occupé et laissez-I/O port de terminaison du thread il suffit d'envoyer la réponse à un travailleur (pool de threads thread en invoquant de rappel. (vous pouvez vous référer à: Comment .FILET de faire usage de IO Fils ou IO Ports de fin?, http://blog.marcgravell.com/2009/02/async-without-pain.html, HttpWebRequest et I/O ports d'achèvement )

Ce qui concerne.

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