2013-07-08 28 views
6

Ho un problema strano e sporadico con una semplice app di test (applicazione console Visual Studio) che funge da watchdog per un sito Web di ASPX ospitato (non app) inviando semplici richieste http e cronometrando i tempi di risposta. L'ho usato per molte settimane in passato senza questo particolare problema. A volte apparentemente casuali durante il giorno, le mie richieste http non riescono con l'errore sopra riportato. Sembrano essere timeout in quanto le richieste che falliscono richiedono 60 secondi. Dopo un periodo di errori coerenti come sopra (intervalli di tempo casuali da pochi minuti a 90 minuti in un caso), gli errori si arrestano e le risposte http iniziano a tornare senza errori alla velocità normale (in genere circa 0,25). Il client watchdog richiede una ricerca del database molto semplice, solo 1-2 righe di codice sul lato server. Questo è ospitato su un host web condiviso di Windows."Una connessione esistente è stata forzatamente chiusa dall'host remoto" errore sporadico da HttpWebRequest

Posso anche attivare questo comportamento a piacimento aggiornando qualsiasi file .cs sul mio sito host, che, tra le altre cose, causa il riciclo del pool di app. Immediatamente l'app del mio watchdog inizia di nuovo a scadere con l'errore sopra riportato.

Ha l'odore di un qualche tipo di problema di connessione riciclata, poiché se riavvio semplicemente l'app watchdog, funziona correttamente e le risposte tornano al normale ritardo.

Ho provato a impostare request.KeepAlive = false e request.ServicePoint.ConnectionLimit = 1, quelli non hanno aiutato.

Un altro indizio, non riesco a collegarmi con il gestore IIS a uno dei due diversi siti Web ospitati su questo server, che ha sempre funzionato bene. Sto ottenendo "La connessione sottostante è stata chiusa" cercando di connettersi tramite Gestione IIS. Ogni volta. Non ho aggiornato nessuno dei siti per un po ', quindi non è stato un mio cambiamento.

Questo è un sito Web asp.net 4 sul backend in esecuzione su IIS7 con un pool di app dedicato in modalità pipeline integrata.

Anche se modifico la variabile sleeptime nell'app watchdog a qualcosa come 30 secondi, il problema non viene visualizzato. C'è un numero magico compreso tra 10 e 20 secondi in cui se le richieste fanno più pause, non falliscono mai.

Penso che il fatto che IIS Manager non riesca a connettersi è una buona prova che qualcosa è sbagliato sul lato host indipendente della mia app di test ma volevo coprire le mie basi prima di aprire un incidente di supporto ... specialmente da un semplice il riavvio della mia app per console risolve il problema ... almeno per un po '.

class Program 
{ 
      //make a simple web request and just return the status code 
    static string SendHttpMsg(string url, string postData) 
    { 
     HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(url)); 
     request.Method = "POST"; 
     request.ContentType = "application/x-www-form-urlencoded"; 
     ASCIIEncoding encoding = new ASCIIEncoding(); 
     byte[] byte1 = encoding.GetBytes(postData); 
     request.ContentLength = byte1.Length; 
     //request.KeepAlive = false; //no effect 
     //request.ServicePoint.ConnectionLimit = 1; //no effect 
     Stream requestStream = request.GetRequestStream(); 
     requestStream.Write(byte1, 0, byte1.Length); 
     requestStream.Close(); 
     HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 
     response.Close(); 
     return ((int)response.StatusCode).ToString(); 
    } 

    static void Main(string[] args) 
    { 
     int sleeptime = 5000; 
     string result = ""; 
     while (true) 
     { 
      DateTime start = DateTime.Now; 
      try 
      { 
       //this is a very simple call that results in a very simple, fast query in the database 
       result = SendHttpMsg("http://example.com/somepage.aspx", "command=test"); 
      } 
      catch (Exception ex) 
      { 
           //fancy exception handling here, removed 
      } 
      DateTime end = DateTime.Now; 
      TimeSpan calltime = end - start; 
      Console.WriteLine(end.ToString() + ", " + calltime.TotalSeconds.ToString("F") + " seconds " + result); 
      Thread.Sleep(sleeptime); 
     } 
    } 
} 

risposta

4

Si potrebbero avere collegamenti pendenti e in HTTP 1.1 ci si limita a 2 connessioni.

Prova changing the HTTP Protocol Version used in the request:

request.ProtocolVersion = HttpVersion.Version10; 

Se questo non funziona, si potrebbe prendere un long time to resolve the proxy settings, che può essere risolto disattivando le impostazioni proxy nell'applicazione aggiungendo il seguente al file .config:

<system.net> 
    <defaultProxy enabled="false"> 
    <proxy/> 
    <bypasslist/> 
    <module/> 
    </defaultProxy> 
</system.net> 

Se una delle correzioni di cui sopra il problema, mi consiglia l'aggiunta di un try ... catch ... finally intorno al vostro codice di richiesta, per garantire che ogni richiesta sia ben chiuso e smaltiti (provate impostazione request = null i n la tua affermazione finale all'interno del metodo).

+0

Grazie, impostazione request.ProtocolVersion = HttpVersion.Version10 ha risolto il problema, rendendo chiaro che avevi giuste connessioni penzolanti, che mi hanno portato a http: // StackOverflow.it/questions/5827030/httpwebrequest-time-out-on-second-call ... la soluzione stava aggiungendo sia request.ServicePoint.ConnectionLeaseTimeout = 5000 e request.ServicePoint.MaxIdleTime = 5000, nel caso del riciclaggio del sito web, la connessione locale è stata riciclata all'interno del mio tempo di ritardo del loop. Funziona alla grande ora! –

Problemi correlati