Megosztás a következőn keresztül:


Adatok gyorsítótárazása az alkalmazás indításakor (VB)

által Scott Mitchell

PDF letöltése

Minden webalkalmazásban gyakran használnak bizonyos adatokat, és egyes adatokat ritkán használnak fel. Az ASP.NET alkalmazás teljesítményét úgy javíthatjuk, hogy előre betöltjük a gyakran használt adatokat, egy úgynevezett technikát. Ez az oktatóanyag bemutatja a proaktív betöltés egyik megközelítését, vagyis az adatok gyorsítótárba való betöltését az alkalmazás indításakor.

Bevezetés

Az előző két oktatóanyag az adatok gyorsítótárazását vizsgálta a prezentációs és gyorsítótárazási rétegekben. Az Adatok gyorsítótárazása az ObjectDataSource-nal című témakörben az ObjectDataSource gyorsítótárazási funkcióit használtuk az adatok gyorsítótárazásához a bemutatórétegben. Az architektúra adatainak gyorsítótárazását egy új, különálló gyorsítótárazási rétegben vizsgálták. Mindkét oktatóanyag reaktív betöltést használt az adatgyorsítótár használatakor. Reaktív betöltéssel minden alkalommal, amikor az adatokat kérik, a rendszer először ellenőrzi, hogy a gyorsítótárban van-e. Ha nem, akkor a forrásból, például az adatbázisból szerzi be az adatokat, majd a gyorsítótárban tárolja. A reaktív terhelés fő előnye a könnyű megvalósítás. Hátrányai közé tartozik, hogy a teljesítménye egyenetlen a kérések során. Képzeljen el egy oldalt, amely az előző oktatóanyag gyorsítótárazási rétegét használja a termékinformációk megjelenítéséhez. Ha ezt a lapot első alkalommal látogatják meg, vagy a gyorsítótárazott adatok memóriakorlátozások vagy a megadott lejárati idő elérése miatt történő kiürítése után először látogatják meg, az adatokat le kell kérni az adatbázisból. Ezért ezek a felhasználói kérések hosszabb időt vesznek igénybe, mint a gyorsítótár által kiszolgálható felhasználói kérések.

A proaktív betöltés alternatív gyorsítótárkezelési stratégiát biztosít, amely a gyorsítótárazott adatok szükség előtti betöltésével kisimítja a kérések teljesítményét. A proaktív betöltés általában valamilyen folyamatot használ, amely rendszeres időközönként ellenőrzi vagy értesítést küld a mögöttes adatok frissítéséről. Ez a folyamat ezután frissíti a gyorsítótárat, hogy friss maradjon. A proaktív betöltés különösen akkor hasznos, ha a mögöttes adatok lassú adatbázis-kapcsolatból, webszolgáltatásból vagy más, különösen lassú adatforrásból származnak. Ez a proaktív betöltési módszer azonban nehezebben implementálhető, mivel ehhez létre kell hoznia, kezelnie és üzembe kell helyeznie egy folyamatot a módosítások ellenőrzéséhez és a gyorsítótár frissítéséhez.

A proaktív betöltés egy másik változata, és az oktatóanyagban megismert típus az adatok betöltése a gyorsítótárba az alkalmazás indításakor. Ez a módszer különösen hasznos statikus adatok, például az adatbázis-keresési táblák rekordjainak gyorsítótárazásához.

Megjegyzés:

A proaktív és reaktív betöltés közötti különbségek, valamint az előnyök, hátrányok és megvalósítási javaslatok listájának részletesebb megtekintéséhez tekintse meg a .NET-keretrendszeralkalmazások gyorsítótárazási útmutatójánakGyorsítótár tartalma című szakaszát.

1. lépés: A gyorsítótárazandó adatok meghatározása az alkalmazás indításakor

Az előző két oktatóanyagban vizsgált reaktív betöltést használó gyorsítótárazási példák jól működnek az olyan adatokkal, amelyek rendszeres időközönként változhatnak, és nem tart túl sokáig a létrehozásuk. Ha azonban a gyorsítótárazott adatok soha nem változnak, a reaktív betöltéssel használt lejárat felesleges. Hasonlóképpen, ha a gyorsítótárazott adatok létrehozása rendkívül hosszú időt vesz igénybe, azoknak a felhasználóknak, akiknek a kérései üresnek találják a gyorsítótárat, hosszú várakozást kell elviselniük a mögöttes adatok lekérése közben. Fontolja meg a statikus adatok és az olyan adatok gyorsítótárazását, amelyek előállítása rendkívül hosszú időt vesz igénybe az alkalmazás indulásakor.

Bár az adatbázisok sok dinamikus, gyakran változó értékkel rendelkeznek, a legtöbb esetben tisztességes mennyiségű statikus adat is van. Például gyakorlatilag minden adatmodell rendelkezik egy vagy több oszloppal, amelyek rögzített választási lehetőségek adott értékét tartalmazzák. Egy Patients adatbázistáblának lehet egy PrimaryLanguage oszlopa, amelynek értékei lehetnek angol, spanyol, francia, orosz, japán stb. Az ilyen típusú oszlopok gyakran keresési táblák használatával vannak implementálva. Ahelyett, hogy angol vagy francia sztringet tárolnánk az Patients táblában, létrehozunk egy második táblázatot, amely általában két oszlopot tartalmaz – egyedi azonosítót és sztring leírást – minden lehetséges értékhez rögzített rekorddal. A PrimaryLanguage tábla oszlopa a Patients keresési táblában tárolja a megfelelő egyedi azonosítót. Az 1. ábrán John Doe beteg elsődleges nyelve az angol, míg Ed Johnson s orosz.

A Nyelvek tábla egy keresési táblázat, amelyet a Betegek tábla használ

1. ábra: A Languages tábla egy keresési tábla, amelyet a Patients tábla használ

Az új beteg szerkesztésére vagy létrehozására szolgáló felhasználói felület tartalmazza a táblázat rekordjai Languages által kitöltött engedélyezett nyelvek legördülő listáját. Gyorsítótárazás nélkül a rendszernek minden alkalommal le kell kérdeznie a Languages táblát, amikor ezt a felületet meglátogatják. Ez pazarló és szükségtelen, mivel a keresési tábla értékei nagyon ritkán változnak, ha valaha is.

Tárolhatnánk az Languages adatokat ugyanazokkal a reaktív betöltési technikákkal, amelyeket az előző oktatóanyagokban vizsgáltunk. A reaktív betöltés azonban időalapú lejárati időt használ, amely nem szükséges a statikus keresési tábla adataihoz. Bár a reaktív betöltést használva történő gyorsítótárazás jobb lenne, mint ha egyáltalán nem lenne gyorsítótárazás, a legjobb módszer a keresési tábla adatainak proaktív betöltése a gyorsítótárba az alkalmazás indításakor.

Ebben az oktatóanyagban áttekintjük, hogyan gyorsítótárazhatja a keresési tábla adatait és egyéb statikus információkat.

2. lépés: Az adatok gyorsítótárazásának különböző módjainak vizsgálata

Az információk programozott módon gyorsítótárazhatók egy ASP.NET-alkalmazásban különböző megközelítések használatával. A korábbi oktatóanyagokban már láttuk, hogyan használhatja az adatgyorsítótárat. Másik lehetőségként az objektumok programozott módon gyorsítótárazhatók statikus tagok vagy alkalmazásállapot használatával.

Az osztály használatakor általában az osztályt először példányosítva kell létrehozni, mielőtt a tagok hozzáférhetnek. Ha például egy metódust szeretne meghívni az üzleti logikai réteg egyik osztályából, először létre kell hoznunk az osztály egy példányát:

Dim productsAPI As New ProductsBLL()
productsAPI.SomeMethod()
productsAPI.SomeProperty = "Hello, World!"

A SomeMethod meghívása vagy a SomeProperty használata előtt először létre kell hoznunk az osztály egy példányát a New kulcsszó használatával. A SomeMethod és a SomeProperty egy adott példányhoz van társítva. Ezeknek a tagoknak az élettartama a társított objektum élettartamához van kötve. A statikus tagok viszont olyan változók, tulajdonságok és metódusok, amelyek az osztály minden példánya között meg vannak osztva, és ezért élettartamuk az osztályig tart. A statikus tagokat a kulcsszó Sharedjelöli.

A statikus tagok mellett az adatok alkalmazásállapot használatával is gyorsítótárazhatók. Minden ASP.NET alkalmazás egy név- és értékgyűjteményt tart fenn, amely az alkalmazás összes felhasználója és oldala között meg van osztva. Ez a gyűjtemény az HttpContext osztály s Application tulajdonságával érhető el, és egy ASP.NET lap s kód mögötti osztályból használható, például:

Application("key") = value
Dim value As Object = Application("key")

Az adatgyorsítótár sokkal gazdagabb API-t biztosít az adatok gyorsítótárazáshoz, valamint mechanizmusokat biztosít az idő- és függőségalapú lejáratokhoz, a gyorsítótárelemek prioritásához stb. Statikus tagok és alkalmazásállapot esetén az ilyen funkciókat manuálisan kell hozzáadnia a lap fejlesztőjének. Amikor az alkalmazás indításakor az adatok az alkalmazás teljes élettartama alatt gyorsítótárba kerülnek, az adatgyorsítótár előnyei azonban jelentéktelenek lesznek. Ebben az oktatóanyagban a statikus adatok gyorsítótárazásához mindhárom technikát használó kódot fogjuk megvizsgálni.

3. lépés: ASupplierstábla adatok gyorsítótárba helyezése

Az eddig implementált Northwind-adatbázistáblák nem tartalmaznak hagyományos keresési táblákat. A DAL-ban implementált négy DataTables olyan táblákat modellez, amelyek értékei nem statikusak. Ahelyett, hogy egy új DataTable-t a DAL-hez, majd egy új osztályt és metódusokat a BLL-hez adnál, az oktatóanyag kedvéért tegyük fel, hogy a Suppliers tábla adatai statikusak. Ezért ezeket az adatokat az alkalmazás indításakor gyorsítótárazhatjuk.

Első lépésként hozzon létre egy új osztályt StaticCache.cs a CL mappában.

A StaticCache.vb osztály létrehozása a CL mappában

2. ábra: Az StaticCache.vb osztály létrehozása a CL mappában

Hozzá kell adnunk egy metódust, amely indításkor betölti az adatokat a megfelelő gyorsítótár-tárolóba, valamint azokat a metódusokat, amelyek adatokat adnak vissza a gyorsítótárból.

<System.ComponentModel.DataObject()> _
Public Class StaticCache
    Private Shared suppliers As Northwind.SuppliersDataTable = Nothing
    Public Shared Sub LoadStaticCache()
        ' Get suppliers - cache using a static member variable
        Dim suppliersBLL As New SuppliersBLL()
        suppliers = suppliersBLL.GetSuppliers()
    End Sub
    
    <DataObjectMethodAttribute(DataObjectMethodType.Select, True)> _
    Public Shared Function GetSuppliers() As Northwind.SuppliersDataTable
        Return suppliers
    End Function
End Class

A fenti kód egy statikus tagváltozót használ az supplierss SuppliersBLL osztály metódusának GetSuppliers() eredményeinek tárolására, amelyet a LoadStaticCache() metódus hív meg. A LoadStaticCache() metódust az alkalmazás indításakor kell meghívni. Miután betöltötte ezeket az adatokat az alkalmazás indításakor, minden olyan oldal, amelynek a szállítói adatokkal kell dolgoznia, meghívhatja az StaticCache osztály GetSuppliers() metódusát. Ezért az adatbázisnak a szállítók lekérésére irányuló hívása csak egyszer, az alkalmazás indításakor történik.

Ahelyett, hogy statikus tagváltozót használnánk gyorsítótár-tárolóként, használhatjuk az alkalmazás állapotát vagy az adatgyorsítótárat. Az alábbi kód az alkalmazásállapot használatára újrarendezett osztályt mutatja be:

<System.ComponentModel.DataObject()> _
Public Class StaticCache
    Public Shared Sub LoadStaticCache()
        ' Get suppliers - cache using application state
        Dim suppliersBLL As New SuppliersBLL()
        HttpContext.Current.Application("key") = suppliers
    End Sub
    
    <DataObjectMethodAttribute(DataObjectMethodType.Select, True)> _
    Public Shared Function GetSuppliers() As Northwind.SuppliersDataTable
        Return TryCast(HttpContext.Current.Application("key"), _
            Northwind.SuppliersDataTable)
    End Function
End Class

A LoadStaticCache()beszállítói adatokat a rendszer az alkalmazásváltozó kulcsában tárolja. A visszaadott érték a megfelelő típus (Northwind.SuppliersDataTable) a következőből: GetSuppliers(). Bár az alkalmazás állapota a ASP.NET lapok Application("key")kód mögötti osztályaiban érhető el, az architektúrában az aktuális HttpContext.Current.Application("key")állapot lekéréséhez használnunk kellHttpContext.

Hasonlóképpen, az adatgyorsítótár gyorsítótárként is használható, ahogy az alábbi kód is mutatja:

<System.ComponentModel.DataObject()> _
Public Class StaticCache
    Public Shared Sub LoadStaticCache()
        ' Get suppliers - cache using a static member variable
        Dim suppliersBLL As New SuppliersBLL()
        HttpRuntime.Cache.Insert("key", suppliers, Nothing, _
            Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, _
            CacheItemPriority.NotRemovable, Nothing)
    End Sub
    <System.ComponentModel.DataObjectMethodAttribute_
    (System.ComponentModel.DataObjectMethodType.Select, True)> _
    Public Shared Function GetSuppliers() As Northwind.SuppliersDataTable
        Return TryCast(HttpRuntime.Cache("key"), Northwind.SuppliersDataTable)
    End Function
End Class

Ha időalapú lejárat nélkül szeretne elemet hozzáadni az gyorsítótárhoz, használja a System.Web.Caching.Cache.NoAbsoluteExpiration és a System.Web.Caching.Cache.NoSlidingExpiration értékeket bemeneti paraméterekként. Ennek az adatgyorsítótár-metódusnak a túlterhelését azért választottuk, hogy meg tudjuk adni a gyorsítótárelem Insert. A prioritás annak meghatározására szolgál, hogy mely elemeket kell a gyorsítótárból kihozni, ha a rendelkezésre álló memória kevés. Itt a prioritást NotRemovable használjuk, amely biztosítja, hogy ez a gyorsítótárelem ne legyen eltávolítva.

Megjegyzés:

Ez az oktatóanyag megvalósítja a StaticCache osztályt a statikus tagváltozó megközelítésével. Az alkalmazásállapot és az adatgyorsítótár-technikák kódja az osztályfájl megjegyzéseiben érhető el.

4. lépés: Kód végrehajtása az alkalmazás indításakor

Ha egy webalkalmazás első indításakor szeretne kódot futtatni, létre kell hoznunk egy speciális fájlt.Global.asax Ez a fájl tartalmazhat eseménykezelőket az alkalmazás-, munkamenet- és kérésszintű eseményekhez, és itt adhat hozzá olyan kódot, amely az alkalmazás indításakor lesz végrehajtva.

Adja hozzá a fájlt a Global.asax webalkalmazás gyökérkönyvtárához. Ehhez kattintson a jobb gombbal a webhelyprojekt nevére a Visual Studio Megoldáskezelőjében, és válassza az Új elem hozzáadása parancsot. Az Új elem hozzáadása párbeszédpanelen válassza ki a Globális alkalmazásosztály elemtípust, majd kattintson a Hozzáadás gombra.

Megjegyzés:

Ha már rendelkezik fájllal Global.asax a projektben, a Globális alkalmazásosztály elemtípus nem jelenik meg az Új elem hozzáadása párbeszédpanelen.

A Global.asax fájl hozzáadása a webalkalmazás gyökérkönyvtárához

3. ábra: A fájl hozzáadása a Global.asax webalkalmazás gyökérkönyvtárához (ide kattintva megtekintheti a teljes méretű képet)

Az alapértelmezett Global.asax fájlsablon öt metódust tartalmaz egy kiszolgálóoldali <script> címkén belül:

  • Application_Start a webalkalmazás első indításakor hajtja végre
  • Application_End az alkalmazás leállításakor fut
  • Application_Error akkor hajtja végre, amikor egy kezeletlen kivétel eléri az alkalmazást
  • Session_Start új munkamenet létrehozásakor hajtja végre
  • Session_End akkor fut, amikor egy munkamenet lejárt vagy elhagyott

Az Application_Start eseménykezelő csak egyszer lesz meghívva az alkalmazás életciklusa során. Az alkalmazás első alkalommal indul el, amikor ASP.NET erőforrást kérnek az alkalmazástól, és az alkalmazás újraindításáig fut, ami többek között a mappa tartalmának /Bin módosításával, a mappa tartalmának Global.asax módosításávalApp_Code, módosításával vagy a Web.config fájl módosításával történhet. Az alkalmazás életciklusával kapcsolatos részletesebb ismertetésért tekintse meg ASP.NET alkalmazás életciklusának áttekintését .

Ezekben az oktatóanyagokban csak kódot kell hozzáadni a Application_Start metódushoz, ezért nyugodtan távolítsa el a többit. Ebben Application_Startegyszerűen hívja meg az StaticCache s LoadStaticCache() osztály metódust, amely betölti és gyorsítótárazza a szállító adatait:

<%@ Application Language="VB" %>
<script runat="server">
    Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
        StaticCache.LoadStaticCache()
    End Sub
</script>

Csak ennyi van benne! Az alkalmazás indításakor a LoadStaticCache() metódus a BLL-ből szerzi be a szállítói adatokat, és egy statikus tagváltozóban tárolja (vagy bármilyen gyorsítótár-tárolóban, amelyet végül az StaticCache osztályban használt). A viselkedés ellenőrzéséhez állítson be egy töréspontot a Application_Start metódusban, és futtassa az alkalmazást. Vegye figyelembe, hogy a töréspontot az alkalmazás indításakor éri el a rendszer. A későbbi kérések azonban nem okozzák a Application_Start metódus végrehajtását.

Töréspont használatával ellenőrizze, hogy a Application_Start eseménykezelő végrehajtása folyamatban van-e

4. ábra: Az eseménykezelő végrehajtásának ellenőrzéséhez Application_Start használjon töréspontot (kattintson ide a teljes méretű kép megtekintéséhez)

Megjegyzés:

Ha a hibakeresés első indításakor nem éri el a Application_Start töréspontot, az azért van, mert az alkalmazás már elindult. Kényszerítse az alkalmazást az újraindításra a Global.asax vagy Web.config fájlok módosításával, majd próbálkozzon újra. Az alkalmazás gyors újraindításához egyszerűen hozzáadhat (vagy eltávolíthat) egy üres sort az egyik fájl végén.

5. lépés: A gyorsítótárazott adatok megjelenítése

Ezen a ponton az StaticCache osztály rendelkezik a szállítói adatoknak az alkalmazás indításakor gyorsítótárazott verziójával, amely a metódusán GetSuppliers() keresztül érhető el. Ha a bemutatórétegből szeretné használni ezeket az adatokat, használhatunk ObjectDataSource-t, vagy programozott módon meghívhatjuk az StaticCache osztály s metódusát GetSuppliers() egy ASP.NET lap kód mögötti osztályából. Nézzük meg az ObjectDataSource és a GridView vezérlők használatát a gyorsítótárazott szállító adatainak megjelenítéséhez.

Először nyissa meg a AtApplicationStartup.aspx lapot a Caching mappában. Húzzon egy GridView-t az Eszköztárból a tervezőre, és állítsa be a ID tulajdonságát Suppliers. Ezután a GridView intelligens címkéje alapján válasszon egy új ObjectDataSource nevű SuppliersCachedDataSourceobjektumot. Konfigurálja az ObjectDataSource-t az osztály s StaticCache metódusának GetSuppliers() használatára.

Az ObjectDataSource konfigurálása a StaticCache osztály használatára

5. ábra: Az ObjectDataSource konfigurálása az osztály használatára (StaticCache teljes méretű kép megtekintéséhez)

A GetSuppliers() metódussal kérje le a szállítók gyorsítótárazott adatait

6. ábra: A gyorsítótárazott szállító adatainak lekérése a GetSuppliers() módszer segítségével (kattintson ide a teljes méretű kép megtekintéséhez)

A varázsló befejezése után a Visual Studio automatikusan hozzáadja a BoundFields elemeket mindegyik adatmezőhöz a SuppliersDataTable-ban. A GridView és az ObjectDataSource deklaratív korrektúrája a következőhöz hasonlóan néz ki:

<asp:GridView ID="Suppliers" runat="server" AutoGenerateColumns="False" 
    DataKeyNames="SupplierID" DataSourceID="SuppliersCachedDataSource" 
    EnableViewState="False">
    <Columns>
        <asp:BoundField DataField="SupplierID" HeaderText="SupplierID" 
            InsertVisible="False" ReadOnly="True" 
            SortExpression="SupplierID" />
        <asp:BoundField DataField="CompanyName" HeaderText="CompanyName" 
            SortExpression="CompanyName" />
        <asp:BoundField DataField="Address" HeaderText="Address" 
            SortExpression="Address" />
        <asp:BoundField DataField="City" HeaderText="City" 
            SortExpression="City" />
        <asp:BoundField DataField="Country" HeaderText="Country" 
            SortExpression="Country" />
        <asp:BoundField DataField="Phone" HeaderText="Phone" 
            SortExpression="Phone" />
    </Columns>
</asp:GridView>
<asp:ObjectDataSource ID="SuppliersCachedDataSource" runat="server" 
    OldValuesParameterFormatString="original_{0}"
    SelectMethod="GetSuppliers" TypeName="StaticCache" />

A 7. ábrán az oldal látható, ha egy böngészőben tekinti meg. A kimenet ugyanaz, ha lekértük az adatokat a BLL-osztályból SuppliersBLL , de az StaticCache osztály használatával az alkalmazás indításakor gyorsítótárazott szállítói adatok lesznek visszaadva. A viselkedés ellenőrzéséhez az osztály s StaticCache metódusában GetSuppliers() töréspontokat állíthat be.

A gyorsítótárazott szállító adatai egy GridView-ban jelennek meg

7. ábra: A gyorsítótárazott szállító adatai egy GridView-ban jelennek meg (kattintson ide a teljes méretű kép megtekintéséhez)

Összefoglalás

A legtöbb adatmodell tisztességes mennyiségű statikus adatot tartalmaz, amelyek általában keresési táblák formájában implementálva. Mivel ezek az információk statikusak, nincs ok az adatbázis folyamatos elérésére minden alkalommal, amikor ezeket az információkat meg kell jeleníteni. Emellett statikus jellege miatt az adatok gyorsítótárazásakor nincs szükség lejáratra. Ebben az oktatóanyagban megvizsgáltuk, hogyan lehet ezeket az adatokat gyorsítótárba helyezni, az alkalmazás állapotát kihasználni, és egy statikus tagváltozót használni a gyorsítótárazás során. Ezek az információk az alkalmazás indításakor gyorsítótárazva lesznek, és az alkalmazás teljes élettartama alatt a gyorsítótárban maradnak.

Ebben az oktatóanyagban és az előző két oktatóanyagban megvizsgáltuk az adatok gyorsítótárazását az alkalmazás élettartamára vonatkozóan, valamint az időalapú lejáratokat. Az adatbázisadatok gyorsítótárazásakor azonban előfordulhat, hogy az időalapú lejárat nem ideális. A gyorsítótár rendszeres kiürítése helyett optimális lenne, ha csak a gyorsítótárazott elemet ürítené ki a mögöttes adatbázis adatainak módosításakor. Ez az ideális megoldás az SQL Cache-függőségek használatával lehetséges, amelyet a következő oktatóanyagban fogunk megvizsgálni.

Boldog programozást!

Tudnivalók a szerzőről

Scott Mitchell, hét ASP/ASP.NET-könyv szerzője és a 4GuysFromRolla.com alapítója, 1998 óta dolgozik a Microsoft webtechnológiáival. Scott független tanácsadóként, edzőként és íróként dolgozik. Legújabb könyve Sams Tanuld meg ASP.NET 2.0 24 óra alatt. Ő itt elérhető mitchell@4GuysFromRolla.com.

Külön köszönet

Ezt az oktatóanyag-sorozatot sok hasznos véleményező áttekintette. Az oktatóanyag vezető véleményezői Teresa Murphy és Zack Jones voltak. Szeretné áttekinteni a közelgő MSDN-cikkeimet? Ha igen, írj egy sort a mitchell@4GuysFromRolla.com-ra.