HttpWebRequest is extreem traag!

Ik gebruik een open source-bibliotheek om verbinding te maken met mijn webserver. Ik was bang dat de webserver extreem traag ging en toen probeerde ik een eenvoudige test in Ruby uit te voeren en ik kreeg deze resultaten

Ruby-programma: 2,11 seconden voor 10 HTTP
GET’s

Ruby-programma: 18,13 seconden voor 100 HTTP
GET’s

C#-bibliotheek: 20,81 seconden voor 10 HTTP
GET’s

C#-bibliotheek: 36847,46 seconden voor 100 HTTP
GET’s

Ik heb me geprofileerd en heb geconstateerd dat het probleem deze functie is:

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;
}

De gemarkeerde regel duurt meer dan 1 seconde om vanzelf te voltooien, terwijl het ruby-programma dat 1 verzoek doet, 0,3 seconden duurt. Ik doe ook al deze tests op 127.0.0.1, dus netwerkbandbreedte is geen probleem.

Wat zou deze enorme vertraging kunnen veroorzaken?

UPDATE

Bekijk de gewijzigde benchmarkresultaten. Ik heb eigenlijk getest met 10 GET’s en niet met 100, ik heb de resultaten bijgewerkt.


Antwoord 1, autoriteit 100%

Wat ik de belangrijkste boosdoener heb gevonden bij trage webverzoeken, is de proxy-eigenschap. Als u deze eigenschap instelt op null voordat u de GetResponse-methode aanroept, slaat de query de stap voor het automatisch detecteren van de proxy over:

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

De automatische detectie van de proxy duurde maximaal 7 seconden voordat het antwoord werd geretourneerd. Het is een beetje vervelend dat deze eigenschap standaard is ingeschakeld voor het HttpWebRequest-object.


Antwoord 2, autoriteit 12%

Het kan te maken hebben met het feit dat je meerdere verbindingen tegelijk opent. Standaard is het maximale aantal open HTTP-verbindingen ingesteld op twee. Probeer dit toe te voegen aan uw .config-bestand en kijk of het helpt:

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

Antwoord 3, autoriteit 6%

Ik had een soortgelijk probleem met een VB.Net MVC-project.
Lokaal op mijn pc (Windows 7) duurde het minder dan 1 seconde om de paginaverzoeken te krijgen, maar op de server (Windows Server 2008 R2) duurde het 20+ seconden voor elk paginaverzoek.

Ik heb een combinatie geprobeerd van het instellen van de proxy op nul

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

En het configuratiebestand wijzigen door toe te voegen

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

Dit verminderde nog steeds niet de trage paginaverzoektijden op de server. Uiteindelijk was de oplossing om de optie “Automatisch instellingen detecteren”uit te vinken in de IE-opties op de server zelf. (Selecteer onder Extra -> Internetopties het tabblad Verbindingen. Druk op de knop LAN-instellingen)

Onmiddellijk nadat ik deze browseroptie op de server had uitgeschakeld, daalden alle paginaverzoektijden van 20+ seconden tot minder dan 1 seconde.


Antwoord 4, autoriteit 5%

Ik begon een vertraging waar te nemen vergelijkbaar met de OP in dit gebied, die een beetje beter werd bij het verhogen van de MaxConnections.

ServicePointManager.DefaultConnectionLimit = 4;

Maar na het bouwen van dit aantal WebRequests kwamen de vertragingen terug.

Het probleem in mijn geval was dat ik een POST belde en me niet druk maakte over het antwoord, dus ik nam niet op of deed er niets mee. Helaas liet dit de WebRequest rondzweven totdat ze een time-out kregen.

De oplossing was om het antwoord op te pikken en het gewoon te sluiten.

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();

Antwoord 5, autoriteit 2%

Gebruik een andere computer dan localhosten gebruik vervolgens WireSharkom te zien wat gaat echt over de draad.

Zoals anderen al hebben gezegd, kan het een aantal dingen zijn. Kijken naar dingen op TCP-niveau zou een duidelijk beeld moeten geven.


Antwoord 6, autoriteit 2%

Ik weet niet precies hoe ik tot deze tijdelijke oplossing ben gekomen, ik had nog geen tijd om wat onderzoek te doen, dus het is aan jullie. Er is een parameter en ik heb deze als volgt gebruikt (in de constructor van mijn klas, voordat ik het HTTPWebRequest-object instantiëerde):

System.Net.ServicePointManager.Expect100Continue = false;

Ik weet niet precies waarom, maar nu zien mijn gesprekken er veel sneller uit.


Antwoord 7

Ik weet dat dit een oude thread is, maar ik heb de hele dag verloren met langzame HttpWebRequest, ik heb elke aangeboden oplossing zonder geluk geprobeerd. Elk verzoek om een ​​adres duurde meer dan een minuut.

Uiteindelijk was het probleem met mijn antivirus-firewall (Eset). Ik gebruik een firewall met interactieve modus, maar Eset is op de een of andere manier volledig uitgeschakeld. Dat zorgde ervoor dat het verzoek voor altijd duurde. Nadat Eset is ingeschakelden het verzoek is uitgevoerd, wordt een prompt firewallbericht weergegeven en na bevestiging het verzoek wordt uitgevoerd voor minder dan één seconde.


Antwoord 8

Voor mij was het gebruik van HttpWebRequestom een ​​API lokaal aan te roepen gemiddeld 40 ms, en het aanroepen van een API op een server gemiddeld 270 ms. Maar bellen via Postman kostte in beide omgevingen gemiddeld 40 ms. Geen van de oplossingen in deze thread maakte voor mij enig verschil.

Toen vond ik dit artikelwaarin het Nagle-algoritme werd genoemd :

Het Nagle-algoritme verhoogt de netwerkefficiëntie door het aantal pakketten dat over het netwerk wordt verzonden te verminderen. Het bereikt dit door een vertraging op de client van maximaal 200 milliseconden in te stellen wanneer kleine hoeveelheden gegevens naar het netwerk worden geschreven. De vertraging is een wachttijd voor aanvullende gegevens die mogelijk worden weggeschreven. Nieuwe gegevens worden aan hetzelfde pakket toegevoegd.

Het instellen van ServicePoint.UseNagleAlgorithmop falsewas de magie die ik nodig had, het maakte een enorm verschil en de prestaties op de server zijn nu bijna identiek aan lokaal.

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

Merk op dat dit voor mij werkte met kleine hoeveelheden gegevens, maar als uw verzoek grote gegevens omvat, kan het de moeite waard zijn om deze vlag voorwaardelijk te maken, afhankelijk van de grootte van het verzoek/verwachte grootte van het antwoord.


9

Voor mij was het probleem dat ik LogMeIn Hamachi – ironisch genoeg had geïnstalleerd om op afstand hetzelfde programma te debuggen dat toen begon met het tonen van deze extreme traagheid.

FYI, uitschakelen De Hamachi-netwerkadapter was niet genoeg omdat het lijkt dat de Windows-service de adapter opnieuw inschakelt.

Ook opnieuw verbinden met mijn Hamachi-netwerk loste het probleem niet op. Alleen de adapter uitschakelen (door middel van het uitschakelen van de LogMeIn Hamachi Windows-service) of, vermoedelijk, het verwijderen van Hamachi, het probleem voor mij opgelost.

Is het mogelijk om HttpWebRequestte vragen om uit te gaan via een specifieke netwerkadapter?


10

Ik ervoer een 15 seconden of zo vertraging bij het creëren van een sessie naar een API via httpwebrequest. De vertraging was rond wachtend op de GetRequestStream (). Na het regelen van antwoorden, vond ik dit artikel en de oplossing was gewoon een lokaal Windows-beleid met betrekking tot SSL:

https: //www.generacodice .com / nl / articolo / 1296839 / httpwebrequest-15-second-delay-uitvoering-probleem


11

We hadden hetzelfde probleem op de web-app. We wachtten op reactie 5 seconden. Wanneer we de gebruiker op aanvraagpool op IIS naar NetworkService wijzigen, begon het antwoord minder dan 1 seconde

te arriveren

Other episodes