2015-11-10 2 views
5

Używamy usługi systemu Windows do wykonywania bardzo częstych połączeń HTTP z wewnętrzną usługą REST (20-40 połączeń na sekundę), ale zauważamy duże opóźnienie w uzyskiwaniu odpowiedzi po uruchomieniu usługi przez kilka minut.HttpWebRequest Port Wyczerpanie

Patrząc na netstat, istnieje sporo portów ze statusem "TIME_WAIT" i wygląda na to, że prawdopodobnie brakuje nam portów.

Jak zapewnić ponowne wykorzystanie portów?

+0

Czy usuwasz instancje żądań po ich zakończeniu? –

+0

Czy używasz również wielu wątków? – CSharpie

+0

Naprawdę, to jest pytanie o wydajność ... nastawiłeś się na to jako przyczyna twoich problemów ... Nie jestem przekonany, że tak. Powiedziałbym, że znacznie częściej jest to objaw innego problemu. – spender

Odpowiedz

1

Istnieje ograniczenie liczby jednoczesnych wychodzących połączeń HTTP. Można to kontrolować za pomocą właściwości statycznych System.Net.ServicePointManager.DefaultConnectionLimit przed tworzenia HttpWebRequest obiektów

warto ustawienie może być to na wyższą wartość niż domyślny, który moim zdaniem jest 2.

Jeśli to nie pomoże, można również zwiększyć domyślny rozmiar ThreadPool, aby umożliwić szybsze tworzenie kolejnych żądań. Pula wątków tylko stopniowo zwiększa liczbę wątków - nowy wątek na każde pół sekundy, IIRC

+0

Dzięki, ale już mają następujące ustawiony w pliku web.config: user2966445

+0

Przeprowadziliśmy również śledzenie, podczas gdy żądania zostały przesłane, a GetRequestStream() średnio 0-1 ms, podczas gdy GetResponse Metoda() zajmuje czasami 60 000ms +. Po stronie odbiorcy widać, że czas przetwarzania odpowiedzi wynosi mniej niż 1000 ms, więc wąskie gardło występuje po stronie wysyłającej. – user2966445

+0

@ user2966445 Czy zapewniasz, że pozbędziesz się wszelkich odpowiedzi itp., Kiedy skończysz? Jeśli to zrobisz, domyślnie C# powinien ponownie używać tego samego bazowego połączenia sieciowego (nie jest to to samo żądanie, ale nie jest możliwe). –

0

Jak możemy zapewnić, że porty są ponownie wykorzystywane? Nie ustawiaj limitu połączenia na wartość, która prawie gwarantuje, że nie będzie.

Wygląda na to, że ktoś w pewnym momencie wprowadził w błąd ServicePointManager. Ograniczałbym ServicePoint dla tego źródła: aby zachęcić do obsługi potoku http i ponownego użycia połączenia:

ServicePointManager.FindServicePoint(Uri).ConnectionLimit = someSensibleValue; 
+0

Już próbowałem ustawienie połączenia max w pliku konfiguracyjnym: user2966445

+0

@ user2966445 Więc Porty efemeryczne wahają się od 49152 do 65535 ... lub 16383.Można sobie wyobrazić, że możesz zużywać tak wysoką wartość. Dlaczego musisz przejść powyżej 10 dla tego hosta? Optymalnie, ile masz równoczesnych żądań bez odpowiedzi? Nie powinieneś potrzebować o wiele więcej połączeń niż ta wartość w normalnych warunkach. Połączenia mogą być ponownie użyte (chyba że zdalnym hostem jest http1.0, wysyłający nagłówki 'connection: close' lub zabijający połączenie). Tak wysoka wartość będzie szkodliwa, ponieważ nie będzie ponownego wykorzystania połączeń, a wygasną one i zbliżą się do TIME_WAIT. – spender