Alkalmazások bemelegítése IIS 7.5 és 8.0 alatt

Mint minden szoftvernél, webalkalmazások esetén is előfordulhat, hogy az alkalmazásnak induláskor inicializálnia kell magát, adatbázis kapcsolatokat kell felépítenie, cache-t kell feltöltenie, sőt az összes olyan rendszer- és platform komponenst is inicializálnia kell, amelyre ráépül. A .NET keretrendszerre épülő alkalmazások esetén ehhez még hozzájön a just-in-time fordítás, mellyel összességében az alkalmazáshoz érkező első kérés kiszolgálása zavaróan elhúzódhat.

Erre a problémára a hagyományos megoldás az, hogy a felhasználói kéréseket megelőzve mi küldjük be az első kérést a webalkalmazásnak, így mire a valódi felhasználók megérkeznek, már a bemelegített, villámgyors honlappal fognak találkozni. Ezzel a megoldással sajnos legalább három probléma van:

  • Meg kell írnunk a kliens szkriptet, ami HTTP kérésekkel bombázza a webalkalmazásunkat.
  • Gondoskodnunk kell arról, hogy a bemelegítő szkriptünk az alkalmazáskészlet minden indulásakor lefusson.
  • IIS 7.5 előtt a felhasználóktól érkező kérések megelőzhetik a bemelegítő szkriptet (architekturális korlát).

Szerencsére a Windows 7-ben és a Windows Server 2008 R2-ben megjelent IIS 7.5 ezen a területen jelentősen fejlődött. A kulcskérdés az, hogy az alkalmazás minek a hatására kezdi el inicializálni magát?

IIS 6 és 7.0 esetén miután megtörtént az alkalmazáskészlet inicializálása, a rendszer készen áll a kérések fogadására, ám az alkalmazás inicializálását valójában az első kérés beérkezése indítja el (katt a teljes képért):

IIS_7_timeline

Ennek következtében a felhasználónak meg kell várnia nem csak az általa beküldött kérés feldolgozását, hanem még a teljes webalkalmazás inicializálását is, és csak utána kapja meg a választ. A helyzetet súlyosbítja, hogy ha van már egy korábbi futó alkalmazáskészlet, akkor azt a webszerver leállítja, miután az új alkalmazáskészlet inicializálása megtörtént – csakhogy ekkor még az új worker processben a webalkalmazás nem áll készen! A felhasználónak tehát nem csak, hogy sokat kell várakoznia, de még az is feltűnik neki, hogy a korábbi gyors rendszer (az előző alkalmazáskészlet már be volt melegítve) hirtelen egy kérés erejéig jelentősen lelassult.

Az IIS 7.5-ben a fejlesztők változtattak a webszerver architektúráján, így az alkalmazáskészlet inicializálása után automatikusan megtörténhet az alkalmazás inicializálása is:

IIS_75_timeline

Ráadásul itt már igazi átlapolt újraindításról (overlapped recycling) beszélhetünk, mert a régi alkalmazáskészlet leállítása csak az után történik meg, hogy az újban az alkalmazás inicializálása is megtörtént, így az első kérést küldő felhasználó egyáltalán nem fogja észrevenni, hogy valójában egy új worker process dolgozza fel a kérését.

Ez a módszer azonban feltételezi azt, hogy a webszerver tudja, hogyan kell a webalkalmazást inicializálni, ami nyilván nem lehet mindig igaz, hiszen nagyon sokféle rendszer létezik. Valójában ez csak úgy tud működni, ha a webalkalmazás fel van készítve erre a funkcionalitásra, ami természetesen egyelőre nem minden alkalmazásra igaz.

Ha az alkalmazásunk még nincs felkészítve az IIS 7.5 új alkalmazáskészlet architektúrájára, akkor nem marad más választásunk, mint a korábbiakhoz hasonlóan HTTP kérésekkel bemelegíteni az alkalmazást. Itt azonban már van arra lehetőségünk, hogy ezek a bemelegítő kérések még az előtt érjék el az alkalmazást, hogy az előző alkalmazáskészlet leállna vagy a felhasználótól kérések érkeznének. Ráadásul egy új modul segítségével még a kérések beküldéséről sem nekünk kell gondoskodnunk.

Korábban az IIS 7.5-höz a Microsoft kiadott egy Application Warm-Up nevű opcionális bővítményt, ami képes volt a beállított URL-ekre a megfelelő időben beküldeni az inicializáló kéréseket. Ez a modul bár nagyon hasznos volt (főként a SharePoint üzemeltetők imádták), még a béta időszak alatt kiderült róla, hogy nem minden szempontból felel meg a Microsoft hosszútávú terveinek, ezért sajnos levették a honlapról és azóta nem volt kész megoldásunk. Az IIS 8-ban azonban beépítetten megjelent ez a funkció Application Initialization néven:

IIS_AppInit_Install

Szerencsére az IIS 7.5 számára is elérhetővé tették ezt a funkciót opcionális bővítmény formájában, aminek most a Release Candidate változata tölthető le innen:

A telepítés nagyon egyszerű next-next-finish, de utána ne keresgéljünk semmit az IIS Managerben, egyelőre nem tartozik ehhez a modulhoz GUI. A beállításokat vagy a config fájlokban, vagy az IIS Manager Configuration Editor moduljával tehetjük meg.

Első lépésként azt célszerű beállítanunk, hogy az application pool mindig fusson (hiszen a leállási időt akarjuk minimalizálni):

 <add name="MyPool" startMode="AlwaysRunning" ... /> 

Ennek hatására a Windows Process Activation Service (WAS) mindig el fogja indítani az alkalmazáskészletet.

A következő lépés a preloading engedélyezése az alkalmazásnál, szintén az applicationHost.config fájlban:

 <application path="/" applicationPool="MyPool" preloadEnabled="true" ... />


Ez fogja kiváltani az első kérést, ami inicializálja az alkalmazást. Már csak az van hátra, hogy meghatározzuk, mi történjen ennél a kérésnél. Ezt legszebben az alkalmazás web.configjában tehetjük meg a system.webServer szekcióban:

<applicationInitialization remapManagedRequestsTo="Loading.html" 
                           skipManagedModules="true" 
                           doAppInitAfterRestart="true"> 
<
add initializationPage="/Default.aspx" />
</
applicationInitialization>

Az add sorokban több URL-t is felsorolhatunk, ahova  kéréseket fog küldeni a modul az alkalmazás inicializálása alatt. A remapManagedRequestsTo attribútumban pedig egy olyan oldalt adhatunk meg, amit válaszként fog visszaküldeni a rendszer az inicializálás ideje alatt (ez persze csak akkor izgalmas, ha nincs átlapolódás az előző alkalmazáskészlettel).

Ezzel készen is vagyunk. Persze lehet még tovább cifrázni, például küldhetünk vissza többféle várakozó képernyőt is, ha összekapcsoljuk az Application Initialization modult az ingyenesen letölthető URL Rewrite modullal. Ezt az teszi lehetővé, hogy az AppInit modul beállítja az APP_WARMING_UP szerver változó értékét 1-re arra az időre, amíg az inicializálás tart. Ebben a cikkben erre is szerepel példa: http://learn.iis.net/page.aspx/1089/iis-80-application-initialization/

 

4 thoughts on “Alkalmazások bemelegítése IIS 7.5 és 8.0 alatt

  1. soci2

    Az átlapolt újraindítás asszem IIS7-től már engedélyezhető az apppolon, ami a gond ezekkel, hogy a fejlesztők abban gondolkodnak, hogy ami statikus, abból egy van. Ezért pl. statukus FileStream példánnyal létrehoznak egy exclusive-an lockolt fájlt, arra számítva, hogy azt csak ők babrálják. És ekkor jön az overlapped recycle…

    1. Balássy György Szerző

      Soci, köszi a hozzászólást, teljesen igazad van. Az ilyen fejlesztővel, vagy inkább architecttel nagyobb gondok vannak, mert nem csak overlapped recyclingra nem gondolt, hanem úgy általában arra, hogy az alkalmazásból több példány futhat. Azaz nem skálázható oldalra az alkalmazása.
      De ha már a humán az oldalt nézzük, említsük meg az üzemeltetőt is, aminek pedig arra kell gondolnia, hogy a két alkalmazás példánynak dupla a memória igénye is.
      Tehát ez egy remek funkció, de ésszel kell használni.

      1. soci2

        Azt hittem lenyelte az előbbi hozzászólásom, de nem.🙂
        A web garden is olyan pont, amikor több példányban fut az app, ráadásul külön os processzekben.

        És gratulálok a megújult MVP-ségedhez.🙂

Vélemény, hozzászólás?

Adatok megadása vagy bejelentkezés valamelyik ikonnal:

WordPress.com Logo

Hozzászólhat a WordPress.com felhasználói fiók használatával. Kilépés / Módosítás )

Twitter kép

Hozzászólhat a Twitter felhasználói fiók használatával. Kilépés / Módosítás )

Facebook kép

Hozzászólhat a Facebook felhasználói fiók használatával. Kilépés / Módosítás )

Google+ kép

Hozzászólhat a Google+ felhasználói fiók használatával. Kilépés / Módosítás )

Kapcsolódás: %s