Comment puis-je prévenir la Prise/Port d'Épuisement?

Je tente de test de performance d'un site web, en la frappant avec les requêtes sur plusieurs threads. Chaque thread exécute n fois. (dans une boucle for)

Cependant, je suis en cours d'exécution dans des problèmes. Plus précisément le WebException ("Impossible de se connecter au serveur distant"), à l'exception interne:

Une opération sur un socket n'a pas pu être effectuée parce que le système
n'avait pas suffisamment d'espace tampon ou à cause d'une file d'attente était pleine
127.0.0.1:52395

Je suis de la tentative d'exécution des threads 100 à 500 itérations par thread.

D'abord j'ai été en utilisant HttpWebRequest dans System.Net pour faire la requête GET au serveur. Actuellement, je suis en utilisant WebClient comme je l'ai supposé que chaque itération a été à l'aide d'un nouveau socket (donc 100 * 500 logements dans un court laps de temps). Je suppose WebClient (qui est instancié qu'une seule fois par sujet) serait d'utiliser uniquement un support.

Je n'ai pas besoin de 50 000 sockets ouverts à la fois, que je voudrais vous envoyer la demande, de recevoir la réponse, et fermer le socket, libérant ainsi de l'utiliser dans la prochaine itération de boucle. Je comprends que ce serait un problème pour

Cependant, même avec WebClient, un tas de sockets sont demandés résultant en un tas de prises en TIME_WAIT mode (vérifiée à l'aide de la commande netstat). Cela entraîne d'autres applications (comme les navigateurs internet) à se bloquer et cesser de fonctionner.

Je peux utiliser mon test avec moins d'itérations et/ou moins de fils, comme il semble que les sockets finalement le faire sortir de cet état TIME_WAIT. Cependant, ce n'est pas une solution car il n'a pas suffisamment tester les capacités du serveur web.

Question:

Comment puis-je fermer explicitement une prise (côté client) après chaque thread itération afin de prévenir TIME_WAIT unis et de la prise d'épuisement?

Code:

Classe qui encapsule le HttpRequest

Edit: Enveloppé WebClient dans une aide, une nouvelle est instancié,utilisés et éliminés pour chaque itération. Le problème persiste encore.

  public sealed class HttpGetTest : ITest {
    private readonly string m_url;

    public HttpGetTest( string url ) {          
        m_url = url;
    }

    void ITest.Execute() {
        using (WebClient webClient = new WebClient()){
            using( Stream stream = webClient.OpenRead( m_url ) ) {          
            }
        }
    }
}

La partie de mon ThreadWrapperClass qui crée un nouveau thread:

public void Execute() {
    Action Hammer = () => {
        for( int i = 1; i <= m_iterations; i++ ) {
            //Where m_test is an ITest injected through constructor
            m_test.Execute();
        }       
    };
    ThreadStart work = delegate {
        Hammer();
    };
    Thread thread = new Thread( work );
    thread.Start();
}
Une chose à considérer est de ne pas tester à l'aide de la "boire au tuyau d'incendie" de la méthode. Vous devriez commencer lentement et augmenter la demande/sec pour un maximum fixé à tester correctement votre système. Ensuite, vous pouvez augmenter votre maximum sur un certain nombre de pistes jusqu'à ce que vous trouver les limites. Internet illimité, les demandes vais vous dire très peu.
Gardez à l'esprit il ya seulement environ 65000 ports disponibles, et pas tous d'entre eux peuvent être utilisés pour les connexions sortantes. Si vous devez utiliser plusieurs adresses ip/Nic pour faire de 50000 connexions que vous essayez de faire
Je comprends que ce serait un problème si j'ai été l'exécution d'un grand nombre de fils, cependant, une fois une itération de la boucle se fait que je n'ai pas le support le plus, mais il colle autour, provoquant la prochaine itération d'ouvrir un nouveau. Je suis à la recherche pour trouver un moyen d'empêcher ça
Vous faites une utilisation sur le stream que vous obtenez de retour, mais pas votre client web. Vous pourriez essayer une instruction d'utilisation sur votre WebClient ainsi afin qu'il soit éliminé. Ou manuellement éliminer une fois que vous avez terminé la lecture.

OriginalL'auteur James | 2012-07-19