HttpWebRequest jest bardzo powolny!

Używam biblioteki open source do łączenia się z moim serwerem WWW. Obawiałem się, że serwer działa bardzo wolno, a potem próbowałem zrobić prosty test w Ruby i dostałem te wyniki

Program Ruby: 2.11 sekund dla 10 HTTP GETs

Program Ruby: 18.13 sekund na 100 HTTP GETs

C# library: 20.81 seconds for 10 HTTP GETs

C # library: 36847.46 seconds for 100 HTTP GETs

Mam profilowane i okazało się, że problemem jest ta funkcja:

private HttpWebResponse GetRawResponse(HttpWebRequest request) {
  HttpWebResponse raw = null;
  try {
    raw = (HttpWebResponse)request.GetResponse(); //This line!
  }
  catch (WebException ex) {
    if (ex.Response is HttpWebResponse) {
      raw = ex.Response as HttpWebResponse;
    }
  }
  return raw;
}

Zaznaczona linia zajmuje ponad 1 sekundę, aby wykonać ją samą, podczas gdy program ruby wykonuje 1 żądanie .3 sekundy. Robię również wszystkie te testy na 127.0.0.1, więc przepustowość sieci nie jest problemem.

Co może być przyczyną tak wielkiego spowolnienia?

UPDATE

Sprawdź zmienione wyniki benchmarku. I rzeczywiście testowane z 10 dostaje, a nie 100, zaktualizowałem wyniki.

Author: Earlz, 2010-03-25

13 answers

To, co znalazłem za głównego winowajcę powolnych żądań internetowych, to właściwość proxy. Jeśli ustawisz tę właściwość NA null przed wywołaniem metody GetResponse, zapytanie pominie krok autodetekcji proxy:

request.Proxy = null;
using (var response = (HttpWebResponse)request.GetResponse())
{
}

Autodetekcja serwera proxy trwała do 7 sekund na zapytanie przed zwróceniem odpowiedzi. Jest to trochę irytujące, że ta właściwość jest domyślnie ustawiona dla obiektu HttpWebRequest.

 175
Author: James Roland,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-03 10:02:50

Może to mieć związek z tym, że otwierasz kilka połączeń jednocześnie. Domyślnie Maksymalna liczba otwartych połączeń HTTP jest ustawiona na dwa. Spróbuj dodać to do swojego .plik konfiguracyjny i sprawdź, czy to pomoże:

<system.net>
  .......
  <connectionManagement>
    <add address="*" maxconnection="20"/>
  </connectionManagement>
</system.net>
 21
Author: Manu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-25 22:16:22

Miałem podobny problem z VB.Net projekt MVC.
Lokalnie na moim komputerze (Windows 7) przejście na żądania stron trwało mniej niż 1 sekundę, ale na serwerze (Windows Server 2008 R2) trwało ponad 20 sekund dla każdego żądania strony.

Próbowałem kombinacji ustawienia proxy na null

  System.Net.WebRequest.DefaultWebProxy = Nothing
  request.Proxy = System.Net.WebRequest.DefaultWebProxy

I zmiana pliku konfiguracyjnego poprzez dodanie

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

To nadal nie zmniejszyło powolnego czasu żądania strony na serwerze. W końcu rozwiązaniem było odznaczenie opcja"Automatycznie wykrywaj ustawienia" w opcjach IE na samym serwerze. (W obszarze Narzędzia -> Opcje internetowe wybierz kartę Połączenia. Naciśnij przycisk Ustawienia sieci LAN)

Natychmiast po tym, jak odznaczyłem tę opcję przeglądarki na serwerze, wszystkie czasy żądania strony spadły z 20 + sekund do poniżej 1 sekundy.

 10
Author: jamieb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-15 16:26:29

Na wykresie dziennym widać, że na wykresie dziennym mamy do czynienia ze spadkiem na poziomie 0.000000.

ServicePointManager.DefaultConnectionLimit = 4;

Ale po zbudowaniu tej liczby Webrequestów opóźnienia wróciły.

Problem w moim przypadku polegał na tym, że dzwoniłem do posta i nie przejmowałem się odpowiedzią, więc nie odbierałem ani nie robiłem nic z tym. Niestety to pozostawiło WebRequest pływające wokół, aż do ich czasu.

Poprawka polegała na odebraniu odpowiedzi i po prostu zamknij.

WebRequest webRequest = WebRequest.Create(sURL);
webRequest.Method = "POST";
webRequest.ContentLength = byteDataGZ.Length;
webRequest.Proxy = null;
using (var requestStream = webRequest.GetRequestStream())
{
    requestStream.WriteTimeout = 500;
    requestStream.Write(byteDataGZ, 0, byteDataGZ.Length);
    requestStream.Close();
}
// Get the response so that we don't leave this request hanging around
WebResponse response = webRequest.GetResponse();
response.Close();
 8
Author: tonycoupland,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-31 10:20:12

Użyj komputera innego niż localhost, a następnie użyj WireShark, aby zobaczyć, co naprawdę dzieje się przez przewód.

Jak mówili inni, może to być wiele rzeczy. Patrząc na rzeczy na poziomie TCP powinno dać jasny obraz.

 3
Author: kervin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-25 22:22:37

Nie wiem, jak dokładnie sięgnąłem do tego obejścia, nie miałem jeszcze czasu na badania, więc to zależy od was. Jest parametr i użyłem go w ten sposób (w konstruktorze mojej klasy, przed utworzeniem instancji obiektu HTTPWebRequest):

System.Net.ServicePointManager.Expect100Continue = false;
Nie wiem dlaczego, ale teraz moje telefony wyglądają dość szybciej.
 3
Author: user753746,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-25 19:52:30

Wiem, że to jakiś stary wątek, ale straciłem cały dzień z powolnym HttpWebRequest, próbowałem każdego dostarczonego rozwiązania bez powodzenia. Każda prośba o adres trwała ponad minutę.

Ostatecznie, problem był z moim firewallem antywirusowym (Eset) . Używam Firewalla z trybem interaktywnym, ale Eset został jakoś wyłączony całkowicie. To spowodowało, że prośba trwała wiecznie. Po włączeniu programu Eset i wykonaniu żądania wyświetlany jest komunikat prompt firewall oraz po potwierdzeniu, żądanie wykonywane przez mniej niż jedną sekundę .

 1
Author: Šemsudin Tafilović,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-11 10:06:12

Próbowałem wszystkich rozwiązań opisanych tutaj bez powodzenia, rozmowa trwała około 5 minut.

Jaki był problem: Potrzebowałem tej samej sesji i oczywiście tych samych plików cookie( żądanie złożone na tym samym serwerze), więc odtworzyłem pliki cookie z żądania.Pliki cookie do WebRequest.CookieContainer . Czas reakcji wynosił około 5 minut.

Moje rozwiązanie: skomentował kod związany z ciasteczkami i bam! Rozmowa trwała mniej niż sekundę.

 0
Author: mihai_omega,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-11 15:26:30

Dla mnie problem polegał na tym, że zainstalowałem LogMeIn Hamachi-jak na ironię, aby zdalnie debugować ten sam program, który zaczął wykazywać tę ekstremalną powolność.

Dla twojej wiadomości, wyłączenie karty sieciowej Hamachi nie wystarczyło, ponieważ wydaje się, że jej usługa Windows ponownie włącza kartę.

Również ponowne podłączenie do sieci Hamachi nie rozwiązało problemu. Tylko wyłączenie adaptera (poprzez wyłączenie usługi LogMeIn Hamachi Windows) lub, przypuszczalnie, odinstalowanie Hamachi, naprawiłeś mi problem.

Czy można poprosić HttpWebRequest o wyjście przez konkretną kartę sieciową?

 0
Author: Craig Silver,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-18 23:03:40

To mi pomogło:

<configuration>
  <system.net>
    <defaultProxy enabled="false"/>
  </system.net>
</configuration>

Kredyt: powolny HTTPWebRequest przy pierwszym uruchomieniu programu

 0
Author: mmmmmm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-04 20:12:23

Dla mnie, używając HttpWebRequest do wywołania API lokalnie średnio 40ms, a do wywołania API na serwerze średnio 270ms. ale wywołanie ich przez listonosza średnio 40ms w obu środowiskach. Żadne z rozwiązań w tym wątku nie zrobiło dla mnie żadnej różnicy.

Potem znalazłem Ten artykuł , który wspomniał o algorytmie Nagle ' a:

Algorytm Nagle zwiększa wydajność sieci poprzez zmniejszenie liczby pakietów wysyłanych przez sieć. Osiąga to poprzez wprowadzenie opóźnienie dla Klienta do 200 milisekund, gdy do sieci zapisywane są niewielkie ilości danych . Opóźnienie to okres oczekiwania na dodatkowe dane, które mogą zostać zapisane. Nowe dane są dodawane do tego samego pakietu.

Ustawienie ServicePoint.UseNagleAlgorithm na false było magią, której potrzebowałem, zrobiło to ogromną różnicę, a wydajność na serwerze jest teraz prawie identyczna z lokalną.

var webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Method = "POST";
webRequest.ServicePoint.Expect100Continue = false;
webRequest.ServicePoint.UseNagleAlgorithm = false; // <<<this is the important bit

Zauważ, że to działało dla mnie z niewielkimi ilościami danych, jednak jeśli twoje żądanie obejmuje duże dane wtedy może być warto uczynić ten znacznik warunkowym w zależności od wielkości żądania / oczekiwanego rozmiaru odpowiedzi.

 0
Author: demoncodemonkey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-17 11:46:53

W moim przypadku dodaj AspxAutoDetectCookieSupport=1 do kodu i problem został rozwiązany

Uri target = new Uri("http://payroll");

string responseContent;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(target);

request.CookieContainer = new CookieContainer();         
request.CookieContainer.Add(new Cookie("AspxAutoDetectCookieSupport", "1") { Domain = target.Host });

using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
    using (Stream responseStream = response.GetResponseStream())
    {
        using (StreamReader sr = new StreamReader(responseStream))
            responseContent = sr.ReadToEnd();
    }
}
 0
Author: ashkufaraz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-11-19 10:47:03

Mieliśmy ten sam problem w aplikacji internetowej. Czekaliśmy na odpowiedź 5 sekund. Kiedy zmieniamy użytkownika w aplikacji IIS na networkService, odpowiedź zaczęła docierać mniej niż 1 sekunda

 -1
Author: user2693593,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-31 09:14:46