L'architettura del nuovo IIS 6

Da Daniele Bochicchio

Da IIS 4 ad IIS 5, l'architettura di Internet Information Services è basata integralmente sul concetto isolamento del processo: le applicazioni web girano in un'area di memoria condivisa in base al livello di isolamento che è stato impostato nella console di gestione.
Esistono tre diversi profili ai quali associare un sito web (o un'applicazione virtuale):

  • Low: è il livello di isolamento più basso. In questo caso l'applicazione girerà nello stesso spazio di memoria di IIS.

  • Medium: è il livello intermedio e quello di default. Tutte le applicazioni condividono questo spazio di memoria, ma IIS ne ha uno separato.

  • High: è il livello di isolamento più alto, che isola del tutto l'applicazione rispetto alle altre ed allo stesso web server.s

Nel caso in cui un'applicazione ha problemi di stabilità, in genere si utilizza la modalità "High isolation", che fa sì che eventuali crash dell'applicazione non influenzino le altre, che in genere si trovano in una modalità di isolamento intermedia. Questo isolamento, però, può portare controindicazioni, come una maggior consumo di risorse e l'impossibilità, ad esempio, di utilizzare alcune funzionalità come CDONTS/CDOsys. Nonostante questo isolamento, ogni applicazione potenzialmente scritta male, sia per sbaglio che volontariamente, può portare al blocco totale del web server, per via della particolare architettura di IIS 5, che ha il servizio che controlla lo stato delle applicazioni all'interno dello stesso eseguibile (e quindi nello stesso processo) del web server.
In parole povere, un'applicazione malfunzionante non solo bloccherà sé stessa, ma con ogni probabilità bloccherà tutte le altre e lo stesso web server, proprio perché il servizio che è preposto al controllo delle applicazioni web gira nello stesso processo del web server, ovvero inetinfo.exe. Quindi se il servizio va in crash, inevitabilmente il processo farà la stessa fine, rendendo di fatto impossibile riavviare automaticamente il servizio.

L'architettura di IIS 6

Tenendo a mente questi difetti, il dev team di IIS ha praticamente riscritto da zero il web server, riprogettando dunque l'architettura perché tenga a mente due requisiti indispensabili per le applicazioni moderne: security e availability.
IIS 5 ha una struttura dei pool di esecuzione differente, e comunque non paragonabile come elasticità di configurazione a quella di IIS 6, che permette di impostare n applicazioni all'interno di un pool particolare, e di isolarne delle altre.
Questo, oltre a consentire l'isolamento di applicazioni che per qualche motivo hanno problemi, permette di configurare in maniera dettagliata tutta una serie di funzionalità, tra cui la memoria massima (virtuale e fisica) che l'applicazione può consumare, così come la CPU massima occupata, ed eventuali politiche di riciclaggio del processo, in base ad esempio ad una data ora, ad un numero massimo di richieste soddisfatte. Si parladi riciclaggio e non riavvio del processo perchè IIS 6 infatti non necessita di riavvii per scaricare la memoria, ma può riciclare i processi in maniera automatica o al verificarsi di problemi particolari. Il riciclare anziché riavviare permette di evitare il down time dovuto al riavvio stesso, perché in pratica si migliora la disponibilità del server, rendendo inutile il riavvio fisico del processo stesso, tranne in casi davvero rari. Il riciclaggio infatti è molto semplice: il servizio web rimane sempre in attesa, ciò che fa è chiudere un particolare processo e crearne uno nuovo, a cui andranno indirizzate le richieste future. In questo modo non si perde nemmeno una richiesta per strada.
IIS 6 si basa dunque su una nuova architettura, completamente rivista rispetto alle versioni precedenti. I componenti principali in gioco ora sono tre: W3SVC, http.sys e W3Core. I primi due rivestono certamente un ruolo molto importante e li analizzeremo subito in dettaglio.

iis6_1

W3SVC è il pezzo meno visibile e pubblicizato della nuova architettura ma non per questo è il meno utile, anzi. E' il servizio che crea e monitora i worker process (i processi che fanno girare le applicazioni web) in base alle informazioni contenute nel metabase, il file di configurazione.
Il parente più vicino di questo servizio è l'amministrazione di IIS 5, che però è parte integrante di inetinfo.exe e quindi è più soggetto a problemi: se inteinfo.exe va in crash, come già detto, l'amministrazione che è parte integrante dello stesso servizio fa la stessa fine, rendendo impossibile il riavvio del processo e bloccando quindi tutte le richieste al servizio web.
Nella versione 6 W3SVC opera come processo indipendente e fa una cosa molto semplice: verifica che ogni applicazione funzioni ed in caso contrario provvede al riavvio. Visto che non c'è codice che gira in questo processo, non è possibile che vada in crash e di conseguenza è sempre possibile riavviare applicazioni in stallo. E' proprio questo il servizio su cui si basa la possibilità di riavviare gli application pools in maniera programmatica, attraverso le impostazioni che preferiamo.

http.sys è invece il più pubblicizzato tra le novità dell'architettura di IIS 6, perché è alla base delle migliorate performance del web server. E' un driver che risiede nel kernel mode e processa le richieste HTTP in arrivo dal web server.
Per capire cosa voglia dire funzionare nel kernel mode, è necessario fare un'analogia con IIS 4 e 5. Questi ultimi girano nello user mode, che è quello poi che il sistema operativo utilizza per tutte le applicazioni, che tra le altre cose non ha accesso diretto all'hardware.
Come conseguenza si basa su procedure particolari (le API) per avere funzionalità specifiche, come lavorare sui driver di rete, salvare un file, o inviare il risultato attraverso le schede di rete stesse. Il cambio di stato, da kernel a user mode, di una esecuzione è operazione assai dispendiosa in termini di consumo di risorse. Utilizzando un driver nel kernel mode, IIS 6 ha accesso diretto alle funzionalità di rete, senza bisogno di passare attraverso questo switch di contesto per utilizzare Winsock. Con alti carichi questo piccolo tempo necessario a cambiare il contesto si traduce in un'ottimizzazione della velocità di risposta del web server.

IIS 6 continua a girare nello user mode (più sicuro perché, per l'appunto, in grado di avere meno privilegi) ma dipende da http.sys che invece è nel kernel mode e che si occupa di ricevere le richieste, decidere a quale worker process girarle e quindi restituire la risposta.
Ovviamente il driver è fatto in modo tale da evitare che un utente possa farci girare codice in grado di provocare un crash nel driver stesso, rendendo quindi impossibile fermare IIS 6 in questo modo.
Tra le altre funzionalità che http.sys ha in carico c'è la gestione dei logs. In questo modo il driver scrive i logs in maniera più veloce e previene "scontri" tra più worker process che tentano contemporaneamente di scrivere sullo stesso file di log, rendendo più inoltre veloce l'operazione. Tra l'altro http.sys è in grado di registrare errori particolari in un file specifico, httperr.log, che è utile ad esempio quando il driver non è in grado di contattare il worker process, perché quest'ultimo è andato in crash, è in riciclo, oppure quando un utente invia una richiesta parziale al server stesso. In questo modo è possibile dare un'occhiata a questo log per ottimizzare il servizio.

Cos'è un application pool?

Gli application pools sono completamente configurabili dall'utente, dunque non esistono dei profili particolari, ma di fatto possiamo creare quanti profili vogliamo, in base alle esigenze che una certa applicazione, o un insieme di esse, ha manifestato.
Un application pool, come il nome stesso dice, non è altro che un pool, un insieme di applicazioni, che condivideranno alcune impostazioni ma soprattutto gireranno nello stesso spazio di memoria. A questo punto ci chiederete come si può configurare un web server in modo che gli application pools abbiano una certa logica. Ed infatti mi viene spesso chiesto come agisco nella configurazione degli application pools, visto che è qualcosa che lascia molta fantasia al sistemista. In genere procedo con la creazione di tre aree principali, ognuna per una tipologia di applicazione:

  • una riservata ai siti "normali", che in genere non hanno un grande traffico e non hanno mai dato nel tempo problemi di performance o scalabilità;

  • una riservata ai siti "pericolosi", con politiche di riciclaggio del processo molto aggressive, che fanno sì che un codice potenzialmente pericoloso, vuoi perché scritto male o semplicemente per il troppo carico non mandi in blocco il servizio che l'applicazione offre;

  • una riservata ai siti "protetti", con politiche di riciclaggio più blande, al fine di garantire la funzionalità del servizio ed evitare continui ricicli del processo.

L'ultima "zona" potrebbe risultare poco utile. In realtà ci sono siti che utilizzano le variabili Session (cosa che in genere evito di fare, visto che ci sono altri sistemi per fare la stessa cosa) e che quindi sono soggetti in maniera più evidente all'unico limite del riciclaggio del processo: viene scaricata la memoria occupata e quindi di fatto si perdono variabili Session ed Application. Se dunque avete un sito di e-commerce, non potete permettervi di far perdere il carrello al cliente solo perché avete deciso di riciclare il processo in maniera così frequente. Meglio creare una zona specifica in cui collocare queste applicazioni, magari proprio una per ogni sito, in modo da tenere separate dalle altre eventuali applicazioni più importanti.
Tra l'altro queste sono tre zone che racchiudono applicazioni molto diffuse, ma nulla ci vieta di creare una zona per ogni singolo sito (anzi, in ambiente di hosting condiviso basato su IIS6 è così che in genere si dovrebbe fare) o addirittura ogni singola applicazioni contenuta in un sito, visto che un sito potrebbe contenere più applicazioni web al suo interno.
Gli application pools ci permettono di evitare che un'applicazione, anche solo un pezzo di codice, possa influenzare il comportamento delle altre e del web server stesso, e quindi il loro utilizzo è consigliato in tutti i casi in cui serva suddividere il carico ma anche la protezione.

Creare un nuovo application pool

Alla base di tutto il discorso fatto finora c'è ovviamente la creazione di un application pool in base alle nostre esigenze, da associare ad esempio ad un solo sito.
Di default ne è presente uno solo, creato in fase di installazione di IIS 6, che lo ricordo ancora una volta non è installato di default, ma deve essere abilitato dal sistemista.
E' sufficiente aprire il tool di gestione di IIS, ad esempio tramite Manage your server, alla voce application server e posizionarsi poi all'interno dell'elenco degli application pools per crearne uno nuovo. A questo punto è necessario andare nelle proprietà del sito che vogliamo associare a questo specifico application pool e procedere con l'operazione, selezionado il tab "Home Directory" ed impostando l'application pool appena creato quale valore dell'omonima impostazione.

Da ora in poi il nostro sito farà riferimento all'application pool appena creato, per cui è necessario "solamente" impostare le proprietà relative a quest'ultimo perché il sito rientri nelle opzioni appena specificate.
Cerchiamo un attimo di esplorare quindi le proprietà dell'application pool appena creato, per impostarne al meglio le proprietà. Ci basta dunque visualizzare la maschera relativa alle impostazioni dell'application pool. In base alla funzionalità che vogliamo regolare, avremo altrettante maschere su cui operare:

  • Recycling

  • Performance

  • Health

  • Identity

Analizziamole tutte in dettaglio, per dare un significato migliore a ciò che è possibile impostare.

Prima impostazione: Recycling

La prima maschera è relativa alla gestione delle politiche di riciclaggio del worker process. E' probabilmente il punto più importante, perché permette di impostare un numero di richieste oppure un numero di minuti dopo le quali scaricare la memoria. Molto più utile la prima, che permette effettivamente di alleggerire il carico dopo aver soddisfatto un numero specifico di richieste, che la seconda, che è qualcosa di più empirico, perché basato sullo scorrere del tempo: per assurdo potrei avere 10 minuti senza richieste, ma averne 100 mila in 5 minuti, nel secondo caso non farebbe nessuna differenza.
Molto interessante anche la possibilità di effettuare il riciclaggio ad orari fissati, che può tornare utile in scenari quali siti ad alto carico, che così possono scaricare la memoria ogni giorno, durante le ore notturne, e quindi rendere più stabile l'application pool e quindi il server stesso, ma anche in siti instabili, che così possono essere tamponati, in attesa di sistemarne il codice.
Ultima possibilità è quella relativa alla memoria massima che il sistema permette di allocare per ogni singolo worker process, che permette di mettere un tetto limite al consumo che un application pool e quindi i worker process che girano all'interno possono effettuare. Questa impostazione è utile sia per le pagine ASP, che tendono a consumare risorse se non opportunamente create, sia per quelle ASP.NET dopo l'utilizzo massiccio dei meccanismi nativi di Caching può portare a consumare molta RAM, ma è più in generale utile anche per limitare l'impatto che le variabili Session possono avere su un web server.

iis6_2

Seconda impostazione: Performance

Se la prima maschera è relativa alle politiche con il cui il worker process (o i worker process) dell'application pool deve essere riciclato, la seconda è relativa alle performance che l'application pool deve garantire.
In realtà anche attraverso questa maschera andremo ad impostare delle politiche sul riciclaggio del processo, ma questa volta agendo sulle performance minime o meglio sul consumo massimo di risorse che W3SVC può concedere allo stesso.

Particolarmente utile è la caratteristica di scaricare il processo se lo stesso rimane in attesa per più di un numero specificato di minuti, così come il numero massimo di richieste nella queue, ovvero nella coda, in attesa di essere eseguite.
Sono entrambi segni, infatti, di un'applicazione che non gode di ottima salute…
E' poi possibile limitare la CPU massima che un'applicazione può occupare, caratteristica molto utile in ambiente di hosting, ed impostare il numero di worker process associati all'application pool, cosa che permette di implementare una web garden, come spiegato qualche paragrafo in alto. Il valore di default è ovviamente 1, ma impostando questo valore su un numero differente vi ritroverete, aprendo il Task Manager, n istanze memoria pari al numero che avete appena specificato.

iis6_3

Terza impostazione: Health

La terza maschera si riferisce invece alla salute dell'application pool e dei worker process associati. In parole povere si tratta della possibilità di impostare alcuni parametri che serviranno per tenere in buona salute i worker process associati.Si parte dal numero massimo di crash che in un lasso di tempo il worker process può avere, fino al timeout in fase di startup e shutdown: tutti segnali che probabilmente qualcosa non funziona a dovere e che con questa maschera potete tenere sotto controllo per evitare ulteriori guai.

iis6_4

Quarta impostazione: Identity

Dallo screenshot potrebbe sembrare la maschera meno importante, in realtà è tra le opzioni più utili, perché permette di associare un utente all'application pool e quindi al worker process.
Di default è presente un nuovo utente, Network Service, con privilegi bassi, per evitare che uno script possa compiere operazioni potenzialmente dannose per il server.
Ciò che risulta interessante è lo stretto connubio che questa impostazione ha con il worker process di ASP.NET. Se non gira in emulazione IIS5 ma in ambiente nativo IIS 6 il file machine.config di ASP.NET viene totalmente ignorato per quanto riguarda la configurazione delle impostazioni che abbiamo analizzato finora. Molte di queste funzionalità, infatti, sono già utilizzabili relativamente al solo worker process ASP.NET, anche in ambiente IIS 5 nativo, ma assumono un valore nettamente più significativo se applicato all'intero web server, in quanto permettono di avere un controllo assoluto su ciò che l'applicazione sta effettuando da un punto di vista decisamente privilegiato quale è quello che il web server è in grado di garantirsi.

Dunque con questa impostazione anche ASP.NET utilizzerà l'utente specificato per l'accesso al file system ed alle risorse del sistema. Questo rappresenta una soluzione migliore dell'uso della cosiddetta impersonation, perché permette di gestire più facilmente il paradigma "un utente per sito", con relativi privilegi, alla base di un sistema di hosting basta su Windows Server System che voglia definirsi quanto meno decente.
Ovviamente bisognerà tenere a mente che una volta selezionato un utente in questa maschera, si dovrà poi provvedere a specificare in maniera corrispondente i permessi di accesso sul file system, eventualmente anche in scrittura, per i files su cui andrà lavorare, oltre che eventualmente creare un accesso a SQL Server qualora si utilizzi la trusted authentication.

iis6_5

Conclusioni

Sugli application pool non si trova molta documentazione, ma anche grazie al nuovo metabase di IIS 6, completamente basato su XML, questa caratteristica a mio modo di vedere finisce con il rivistire un'importanza senza dubbio primaria nell'ambito delle nuove caratteristiche di IIS 6.
Questo articolo ha quindi lo scopo di mettervi a conoscenza delle nuove ed utilissime possibilità che IIS 6 offre a chi ogni giorno si occupa sì di sviluppo web, ma anche di amministrazione.
L'augurio è di instaurare subito un ottimo rapporto con il prodotto, perché è senza dubbio tra i migliori web server attualmente in circolazione, in grado di garantire flessibilità nella configurazione, ma anche sicurezza ed affidabilità nell'uso quotidiano.