2012-02-27 13 views
6

Ho un'applicazione server complessa che utilizza Nhibernate e Linq2SQL. Circa 3 volte al giorno il codice Linq2sql genera un'eccezione "valore non può essere nulla". Quando ciò accade, il codice genererà sempre l'eccezione. La diagnosi e la risoluzione della causa principale saranno lunghe e introdurranno instabilità.Come posso riciclare a livello di codice un apppool di app .net?

L'attuale "correzione" consiste nel rieseguire il pool di app ogni ora. Tuttavia, il servizio è inattivo dal punto in cui si verifica il problema fino a quando non si verifica il riciclo. Voglio che il servizio Web rilevi l'eccezione e ricicli il proprio pool di app. Voglio che tutte le altre richieste web vengano onorate fino al completamento.

Modifica: L'errore si verifica su entrambi i server in una Web farm con carico bilanciato. I client non passano da un server all'altro solo perché questo codice si arresta in modo anomalo.

+2

'diagnosi e risolvere la causa principale sarà lungo e introdurrà instability' prima downvotealanche. È necessario configurare il pool di applicazioni per riciclare a breve termine e correggere il bug a lungo termine. – Will

+0

Grazie. Questo è il piano –

+0

L'approccio migliore sarà quello di correggere l'errore –

risposta

18

Il seguente codice ricicla il pool di app del sito corrente. È necessario aggiungere un riferimento a Microsoft.Web.Administration

using (ServerManager iisManager = new ServerManager()) 
{ 
    SiteCollection sites = iisManager.Sites; 
    foreach (Site site in sites) 
    { 
     if (site.Name == HostingEnvironment.ApplicationHost.GetSiteName()) 
     { 
     iisManager.ApplicationPools[site.Applications["/"].ApplicationPoolName].Recycle(); 
     break; 
     } 
    } 
} 
+6

Questa dovrebbe essere accettata risposta. – vittore

+0

@vittore Hanno un problema simile a OP, e questo non lo taglierà. L'APPPOOL non ha i diritti per rimuoverlo, quindi forse non funziona neanche per OP. La soluzione dell'OP avrebbe funzionato per me, ma sembra semplicemente * inquietante *;) facendo così. – ClasG

+0

@ClasG Sì, hai bisogno di autorizzazioni estese per farlo funzionare – vittore

0

Quest'ultima frase era un killer.

Per ottenere ciò, è necessario implementare un'impostazione di bilanciamento del carico che sarà molto più complessa rispetto alla risoluzione del problema originale.

Ti suggerisco di dedicare un po 'di tempo a risolvere quell'eccezione. Si prega di inviare un po 'di codice dalla query Linq pertinente, forse potremmo offrire alcuni suggerimenti lì.

+1

Se si desidera risolvere il problema sottostante, si prega di inviare una nuova domanda: la domanda originale e il problema sono problemi molto separati. –

+0

Voglio risolvere il problema di fondo e sì hai ragione, è un compito completamente diverso. Ma questo non è un lavoro per questo mese. –

3

Il modo più semplice per "trip" il processo di lavoro ASP.NET nel riciclaggio di un pool di applicazioni consiste nel modificare il file web.config in qualche modo. Questa modifica viene rilevata dal watcher del file system e causa il riciclo di ASP.NET per caricare la nuova configurazione.

Il contenuto del file non deve essere modificato in alcun modo pratico; è sufficiente aggiungere o rimuovere il carattere degli spazi bianchi.

Edit:

Se questo non è abbastanza forte per aggirare il problema, si può andare fino in fondo e utilizzare i servizi Directory per riciclare il pool di app manualmente.

// Set up the path identifying your application pool. 
var path = "IIS://YOURSERVERNAME/W3SVC/AppPools/YourAppPoolName"; 

// Create the directory entry to control the app pool 
var appPool = new DirectoryEntry(path); 

// Invoke the recycle action. 
appPool.Invoke("Recycle", null); 

Basato su Code Project: Recycling IIS 6.0 application pools programmatically.

+0

Toccando web.config, anche se concedo esplicitamente diritti di scrittura a IUSR (si ricorda un cerotto), ricicleremo solo l'APPLICAZIONE, non l'APP POOL. Il problema dei dati è nel pool di app e il processo w3wp continua allegramente –

+0

Aggiornato con un approccio più diretto. Non è stato verificato che funzioni su IIS7 +, quindi facci sapere come vai avanti. –

+0

Inizialmente avevo intrapreso questo percorso ma l'elenco delle autorizzazioni richieste era oneroso e complesso. Ho optato per una soluzione molto più semplice, che consisteva nell'abilitare il riciclo delle impostazioni del pool di app al superamento del valore memoryLimit, allocando quindi deliberatamente la memoria fino a quando non è scattato il riciclo. –

0

Ho già avuto lo stesso identico problema; Avrei dovuto bloggarlo perché ora non riesco a ricordare la causa principale.

Il mio istinto mi dice, è stato uno dei seguenti modi:

  1. Un contesto non sempre disposti da qualche parte.
  2. Problema di collegamento: assicurarsi che più thread non possano accedere allo stesso contesto.

O qualcosa del genere. Assicurati di utilizzare correttamente Linq2Sql.

0

La soluzione che alla fine ho scelto era di impostare un valore massimo per la quantità di memoria che l'appPool era autorizzato a consumare. Il codice poi ha semplicemente inghiottito la memoria finché asp.net ha deciso di riciclare l'appPool.

Nelle impostazioni avanzate del pool di app ho impostato il limite di memoria privata su 800.000 Kb.

Nella sezione di cattura in cui il codice Linq fallito, ho allocare più memoria rispetto al limite:

List<string> listOfMemory = new List<string>(); 

// in the app pool, you need to set the virtual memory limit to 800,000kb 
log.Error("Allocating so much memory that the app pool will be forced to recycle... "); 
for (int intCount = 1; intCount < 10000000; intCount++) 
{ 
listOfMemory.Add("new string " + intCount.ToString()); 
} 

Questo significa che ora solo circa 4 fili sicuro prima di un nuovo processo w3wp viene generato. Prima di questa soluzione, i thread fallivano costantemente fino a quando un utente non ha riciclato manualmente il pool di applicazioni. Sfortunatamente, se si imposta il pool di app per il riciclo su un numero regolare di minuti, minore è il numero di minuti più spesso l'arresto anomalo. E più grande è il numero di minuti, più thread fallirebbero.

Questa soluzione alternativa limita il danno.

+0

Anche se questo potrebbe essere adatto al tuo ambiente, potrebbe anche forzare temporaneamente il server se: la tua app utilizza 200 mb memoria, il server ha 400 mb di memoria libera, la tua app inizia ad allocare memoria. A questo punto è necessario 600 mb per forzare un riciclo, e il server inizierà a pagina pesantemente dopo 400 mb è allocato. –

+0

Wow ... piuttosto brutto. Ma anche se vuoi farlo in questo modo, perché non solo nuovo [] quale quantità di RAM vuoi allocare? –

Problemi correlati