Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Figyelmeztetés
A ASP.NET Core ezen verziója már nem támogatott. További információt a .NET és a .NET Core támogatási szabályzatában talál. A jelen cikk .NET 9-es verzióját lásd az aktuális kiadásért .
Fontos
Ezek az információk egy olyan előzetes termékre vonatkoznak, amelyet a kereskedelmi forgalomba kerülés előtt jelentősen módosíthatnak. A Microsoft nem vállal kifejezett vagy hallgatólagos szavatosságot az itt megadott információkra vonatkozóan.
A jelen cikk .NET 9-es verzióját lásd az aktuális kiadásért .
Ez a cikk bemutatja, hogyan konfigurálhatja a kimeneti gyorsítótárazási köztes szoftvereket egy ASP.NET Core-alkalmazásban. A kimeneti gyorsítótárazásról a Kimeneti gyorsítótárazás című témakörben olvashat bővebben.
A kimeneti gyorsítótárazási köztes szoftver az ASP.NET Core-alkalmazások minden típusában használható: Minimal API, Web API vezérlőkkel, MVC és Razor Pages. A kód példákat biztosít a minimális API-khoz és a vezérlőalapú API-khoz. A vezérlőalapú API-példák bemutatják, hogyan használhatók attribútumok a gyorsítótárazás konfigurálásához. Ezek az attribútumok MVC- és Razor Pages-alkalmazásokban is használhatók.
A kódpéldák egy Gravatar-osztályra vonatkoznak, amely létrehoz egy képet, és időbélyeget ad meg a létrehozás dátuma és időpontja vonatkozásában. Az osztály definiálva van, és csak a mintaalkalmazásban használatos. Célja, hogy könnyen látható legyen, amikor a gyorsítótárazott kimenetet használják. A további információt lásd: Hogyan töltsünk le mintát és Preprocesszor-irányelvek a mintakódban.
Köztes szoftver hozzáadása az alkalmazáshoz
Adja hozzá a kimeneti gyorsítótárazási middleware-t a szolgáltatásgyűjteményhez a AddOutputCache hívásával.
Adja hozzá a köztes szoftvert a kérésfeldolgozó folyamathoz hívással UseOutputCache.
Például:
builder.Services.AddOutputCache();
var app = builder.Build();
// Configure the HTTP request pipeline.
app.UseHttpsRedirection();
app.UseOutputCache();
app.UseAuthorization();
A AddOutputCache
és UseOutputCache
hívása nem indítja el a gyorsítótárazási viselkedést, hanem elérhetővé teszi a gyorsítótárazást. Az alkalmazásgyorsítótár-válaszok létrehozásához a gyorsítótárazást az alábbi szakaszokban látható módon kell konfigurálni.
Megjegyzés:
- A CORS köztes szoftvereket használó alkalmazásokban a
UseOutputCache
függvényt a UseCors után kell meghívni. - A Pages alkalmazásokban és a vezérlőkkel rendelkező alkalmazásokban a Razor meghívását a
UseOutputCache
után kell elvégezni.
Egy végpont vagy lap konfigurálása
Minimális API-alkalmazások esetén konfiguráljon egy végpontot gyorsítótárazásra a CacheOutput
hívásával vagy az [OutputCache]
attribútum alkalmazásával, ahogy az alábbi példák mutatják.
app.MapGet("/cached", Gravatar.WriteGravatar).CacheOutput();
app.MapGet("/attribute", [OutputCache] (context) =>
Gravatar.WriteGravatar(context));
Vezérlőkkel rendelkező alkalmazások esetén alkalmazza az [OutputCache]
attribútumot a műveletmetódusra az itt látható módon:
[ApiController]
[Route("/[controller]")]
[OutputCache]
public class CachedController : ControllerBase
{
public async Task GetAsync()
{
await Gravatar.WriteGravatar(HttpContext);
}
}
A Razor Pages alkalmazások esetében alkalmazza az attribútumot az Razor oldal osztályára.
Több végpont vagy lap konfigurálása
Hozzon létre szabályzatokat, amelyek híváskor több végpontra vonatkozó gyorsítótárazási konfigurációt adnak megAddOutputCache
. A szabályzatok kiválaszthatók adott végpontokhoz, míg az alapszabályzatok alapértelmezett gyorsítótárazási konfigurációt biztosítanak a végpontok gyűjteményéhez.
Az alábbi kiemelt kód az alkalmazás összes végpontjának gyorsítótárazását konfigurálja 10 másodperces lejárati idővel. Ha nincs megadva lejárati idő, az alapértelmezés szerint egy perc.
builder.Services.AddOutputCache(options =>
{
options.AddBasePolicy(builder =>
builder.Expire(TimeSpan.FromSeconds(10)));
options.AddPolicy("Expire20", builder =>
builder.Expire(TimeSpan.FromSeconds(20)));
options.AddPolicy("Expire30", builder =>
builder.Expire(TimeSpan.FromSeconds(30)));
});
Az alábbi kiemelt kód két szabályzatot hoz létre, amelyek mindegyike eltérő lejárati időt ad meg. A kijelölt végpontok használhatják a 20 másodperces lejáratot, mások pedig a 30 másodperces lejáratot.
builder.Services.AddOutputCache(options =>
{
options.AddBasePolicy(builder =>
builder.Expire(TimeSpan.FromSeconds(10)));
options.AddPolicy("Expire20", builder =>
builder.Expire(TimeSpan.FromSeconds(20)));
options.AddPolicy("Expire30", builder =>
builder.Expire(TimeSpan.FromSeconds(30)));
});
A végpont számára szabályzatot választhat a CacheOutput
metódus meghívásakor vagy a [OutputCache]
attribútum használatakor.
Egy minimális API-alkalmazásban az alábbi kód egy végpontot konfigurál 20 másodperces lejárattal, egyet pedig 30 másodperces lejárattal:
app.MapGet("/20", Gravatar.WriteGravatar).CacheOutput("Expire20");
app.MapGet("/30", [OutputCache(PolicyName = "Expire30")] (context) =>
Gravatar.WriteGravatar(context));
Vezérlőkkel rendelkező alkalmazások esetén alkalmazza az [OutputCache]
attribútumot a műveletmetódusra egy szabályzat kiválasztásához:
[ApiController]
[Route("/[controller]")]
[OutputCache(PolicyName = "Expire20")]
public class Expire20Controller : ControllerBase
{
public async Task GetAsync()
{
await Gravatar.WriteGravatar(HttpContext);
}
}
A Razor Pages alkalmazások esetében alkalmazza az attribútumot az Razor oldal osztályára.
Alapértelmezett kimeneti gyorsítótárazási szabályzat
Alapértelmezés szerint a kimeneti gyorsítótárazás a következő szabályokat követi:
- A rendszer csak a HTTP 200-válaszokat gyorsítótárazza.
- Csak a HTTP GET vagy a HEAD kérések gyorsítótárazva vannak.
- Olyan válaszok, amelyek cookie-kat állítanak be, nem kerülnek gyorsítótárazásra.
- A hitelesített kérelmekre adott válaszok nem gyorsítótárazva lesznek.
Az alábbi kód az összes alapértelmezett gyorsítótárazási szabályt alkalmazza az alkalmazás összes végpontjára:
builder.Services.AddOutputCache(options =>
{
options.AddBasePolicy(builder => builder.Cache());
});
Az alapértelmezett szabályzat felülbírálása
Az alábbi kód bemutatja, hogyan bírálhatja felül az alapértelmezett szabályokat. Az alábbi egyéni szabályzatkód kiemelt sorai lehetővé teszik a HTTP POST metódusok és a HTTP 301-válaszok gyorsítótárazását:
using Microsoft.AspNetCore.OutputCaching;
using Microsoft.Extensions.Primitives;
namespace OCMinimal;
public sealed class MyCustomPolicy : IOutputCachePolicy
{
public static readonly MyCustomPolicy Instance = new();
private MyCustomPolicy()
{
}
ValueTask IOutputCachePolicy.CacheRequestAsync(
OutputCacheContext context,
CancellationToken cancellationToken)
{
var attemptOutputCaching = AttemptOutputCaching(context);
context.EnableOutputCaching = true;
context.AllowCacheLookup = attemptOutputCaching;
context.AllowCacheStorage = attemptOutputCaching;
context.AllowLocking = true;
// Vary by any query by default
context.CacheVaryByRules.QueryKeys = "*";
return ValueTask.CompletedTask;
}
ValueTask IOutputCachePolicy.ServeFromCacheAsync
(OutputCacheContext context, CancellationToken cancellationToken)
{
return ValueTask.CompletedTask;
}
ValueTask IOutputCachePolicy.ServeResponseAsync
(OutputCacheContext context, CancellationToken cancellationToken)
{
var response = context.HttpContext.Response;
// Verify existence of cookie headers
if (!StringValues.IsNullOrEmpty(response.Headers.SetCookie))
{
context.AllowCacheStorage = false;
return ValueTask.CompletedTask;
}
// Check response code
if (response.StatusCode != StatusCodes.Status200OK &&
response.StatusCode != StatusCodes.Status301MovedPermanently)
{
context.AllowCacheStorage = false;
return ValueTask.CompletedTask;
}
return ValueTask.CompletedTask;
}
private static bool AttemptOutputCaching(OutputCacheContext context)
{
// Check if the current request fulfills the requirements
// to be cached
var request = context.HttpContext.Request;
// Verify the method
if (!HttpMethods.IsGet(request.Method) &&
!HttpMethods.IsHead(request.Method) &&
!HttpMethods.IsPost(request.Method))
{
return false;
}
// Verify existence of authorization headers
if (!StringValues.IsNullOrEmpty(request.Headers.Authorization) ||
request.HttpContext.User?.Identity?.IsAuthenticated == true)
{
return false;
}
return true;
}
}
Az egyéni szabályzat használatához hozzon létre egy nevesített szabályzatot:
builder.Services.AddOutputCache(options =>
{
options.AddPolicy("CachePost", MyCustomPolicy.Instance);
});
Válassza ki a végpont nevesített szabályzatát. A következő kód kiválasztja egy végpont egyéni szabályzatát egy minimális API-alkalmazásban:
app.MapPost("/cachedpost", Gravatar.WriteGravatar)
.CacheOutput("CachePost");
A vezérlőművelet esetében a következő kód ugyanezt teszi:
[ApiController]
[Route("/[controller]")]
[OutputCache(PolicyName = "CachePost")]
public class PostController : ControllerBase
{
public async Task GetAsync()
{
await Gravatar.WriteGravatar(HttpContext);
}
}
Alternatív alapértelmezett szabályzat felülbírálása
Alternatívaként használja a Függőséginjektálást (DI) egy példány inicializálásához, a következő módosításokkal az egyéni házirend osztályában:
- Magánkonstruktor helyett nyilvános konstruktor.
- Törölje a tulajdonságot
Instance
az egyéni szabályzatosztályból.
Például:
public sealed class MyCustomPolicy2 : IOutputCachePolicy
{
public MyCustomPolicy2()
{
}
Az osztály többi része megegyezik a korábban láthatóval. Adja hozzá az egyéni szabályzatot az alábbi példában látható módon:
builder.Services.AddOutputCache(options =>
{
options.AddPolicy("CachePost", builder =>
builder.AddPolicy<MyCustomPolicy2>(), true);
});
Az előző kód a DI használatával hozza létre az egyéni szabályzatosztály példányát. A konstruktorban lévő nyilvános argumentumok feloldódnak.
Ha egyéni szabályzatot használ alapszabályzatként, ne hívjon meg OutputCache()
(argumentumok nélkül), és ne használja az [OutputCache]
attribútumot olyan végponton, amelyre az alapházirendnek vonatkoznia kell. Az attribútum meghívása OutputCache()
vagy használata hozzáadja az alapértelmezett szabályzatot a végponthoz.
A gyorsítótárkulcs megadása
Alapértelmezés szerint az URL-cím minden része a gyorsítótár-bejegyzés kulcsává válik, azaz a séma, a gazdagép, a port, az elérési út és a lekérdezési sztring. Előfordulhat azonban, hogy explicit módon szeretné szabályozni a gyorsítótárkulcsot. Tegyük fel például, hogy van egy végpontja, amely csak a culture
lekérdezési sztring minden egyedi értékére ad vissza egyedi választ. Az URL más részeinek, például más lekérdezési sztringeknek a variációja nem eredményezhet különböző gyorsítótár-bejegyzéseket. Ezeket a szabályokat megadhatja egy szabályzatban, ahogyan az a következő kiemelt kódban is látható:
builder.Services.AddOutputCache(options =>
{
options.AddBasePolicy(builder => builder
.With(c => c.HttpContext.Request.Path.StartsWithSegments("/blog"))
.Tag("tag-blog"));
options.AddBasePolicy(builder => builder.Tag("tag-all"));
options.AddPolicy("Query", builder => builder.SetVaryByQuery("culture"));
options.AddPolicy("NoCache", builder => builder.NoCache());
options.AddPolicy("NoLock", builder => builder.SetLocking(false));
});
Ezután kiválaszthatja a VaryByQuery
végponthoz tartozó szabályzatot. Egy minimális API-alkalmazásban az alábbi kód kiválasztja egy VaryByQuery
végpont szabályzatát, amely csak a culture
lekérdezési sztring minden egyedi értékére ad vissza egyedi választ:
app.MapGet("/query", Gravatar.WriteGravatar).CacheOutput("Query");
A vezérlőművelet esetében a következő kód ugyanezt teszi:
[ApiController]
[Route("/[controller]")]
[OutputCache(PolicyName = "Query")]
public class QueryController : ControllerBase
{
public async Task GetAsync()
{
await Gravatar.WriteGravatar(HttpContext);
}
}
Íme néhány lehetőség a gyorsítótárkulcs vezérlésére:
SetVaryByQuery – Adjon meg egy vagy több lekérdezési sztringnevet, amely hozzáadható a gyorsítótárkulcshoz.
SetVaryByHeader – Adjon meg egy vagy több HTTP-fejlécet, amely hozzáadható a gyorsítótárkulcshoz.
VaryByValue– Adja meg a gyorsítótárkulcshoz hozzáadni kívánt értéket. Az alábbi példa egy értéket használ, amely azt jelzi, hogy a kiszolgáló aktuális ideje másodpercben páratlan vagy páros. Új válasz csak akkor jön létre, ha a másodpercek száma páratlanról párosra vagy párosra megy.
builder.Services.AddOutputCache(options => { options.AddBasePolicy(builder => builder .With(c => c.HttpContext.Request.Path.StartsWithSegments("/blog")) .Tag("tag-blog")); options.AddBasePolicy(builder => builder.Tag("tag-all")); options.AddPolicy("Query", builder => builder.SetVaryByQuery("culture")); options.AddPolicy("NoCache", builder => builder.NoCache()); options.AddPolicy("NoLock", builder => builder.SetLocking(false)); options.AddPolicy("VaryByValue", builder => builder.VaryByValue((context) => new KeyValuePair<string, string>( "time", (DateTime.Now.Second % 2) .ToString(CultureInfo.InvariantCulture)))); });
A OutputCacheOptions.UseCaseSensitivePaths használatával megadhatja, hogy a kulcs elérési útja kis- és nagybetű érzékeny. Az alapértelmezett érzéketlen a kis- és nagybetűkre.
További lehetőségekért tekintse meg az OutputCachePolicyBuilder osztályt.
Gyorsítótár-újraértékelés
A gyorsítótár-újraértékelés azt jelenti, hogy a kiszolgáló a teljes válasz törzse helyett EGY HTTP-állapotkódot tud visszaadni 304 Not Modified
. Ez az állapotkód tájékoztatja az ügyfelet, hogy a kérésre adott válasz nem változik, mint amit az ügyfél korábban kapott.
Az alábbi kód egy Etag
fejléc használatát mutatja be a gyorsítótár újraértékelésének engedélyezéséhez. Ha az ügyfél egy korábbi válasz etagértékével küld egy If-None-Match
fejlécet, és a gyorsítótár-bejegyzés friss, a kiszolgáló a teljes válasz helyett a 304 Nem módosítva értéket adja vissza. Az alábbi módon állíthatja be az etag értéket egy szabályzatban egy Minimális API-alkalmazásban:
app.MapGet("/etag", async (context) =>
{
var etag = $"\"{Guid.NewGuid():n}\"";
context.Response.Headers.ETag = etag;
await Gravatar.WriteGravatar(context);
}).CacheOutput();
A következő módon állíthatja be az etag értékét egy vezérlőalapú API-ban:
[ApiController]
[Route("/[controller]")]
[OutputCache]
public class EtagController : ControllerBase
{
public async Task GetAsync()
{
var etag = $"\"{Guid.NewGuid():n}\"";
HttpContext.Response.Headers.ETag = etag;
await Gravatar.WriteGravatar(HttpContext);
}
}
A gyorsítótár-újraértékelés másik módja az, hogy összehasonlítjuk a gyorsítótár-bejegyzés létrehozásának dátumát az ügyfél által kért dátummal. A kérelem fejlécének If-Modified-Since
megadásakor a kimeneti gyorsítótárazás 304-et ad vissza, ha a gyorsítótárazott bejegyzés régebbi, és nem járt le.
A gyorsítótár újraértékelése automatikusan történik az ügyféltől érkező fejlécek hatására. Ennek a viselkedésnek az engedélyezéséhez nincs szükség speciális konfigurációra a kiszolgálón, a kimeneti gyorsítótárazás engedélyezésén kívül.
Gyorsítótár bejegyzések eltávolítása címkék használatával
Címkék használatával azonosíthatja a végpontok egy csoportját, és kizárhatja a csoport összes gyorsítótár-bejegyzését. Az alábbi minimális API-kód például létrehoz egy olyan végpontpárt, amelynek URL-címei "blog"-tal kezdődnek, és címkézik a "tag-blog" címkét:
app.MapGet("/blog", Gravatar.WriteGravatar)
.CacheOutput(builder => builder.Tag("tag-blog"));
app.MapGet("/blog/post/{id}", Gravatar.WriteGravatar)
.CacheOutput(builder => builder.Tag("tag-blog"));
Az alábbi kód bemutatja, hogyan rendelhet címkéket egy végponthoz egy vezérlőalapú API-ban:
[ApiController]
[Route("/[controller]")]
[OutputCache(Tags = new[] { "tag-blog", "tag-all" })]
public class TagEndpointController : ControllerBase
{
public async Task GetAsync()
{
await Gravatar.WriteGravatar(HttpContext);
}
}
A kezdő útvonalakkal blog
rendelkező végpontok címkéinek hozzárendelésének másik módja egy olyan alapházirend meghatározása, amely az adott útvonallal rendelkező összes végpontra érvényes. A következő kód bemutatja, hogyan teheti ezt meg:
builder.Services.AddOutputCache(options =>
{
options.AddBasePolicy(builder => builder
.With(c => c.HttpContext.Request.Path.StartsWithSegments("/blog"))
.Tag("tag-blog"));
options.AddBasePolicy(builder => builder.Tag("tag-all"));
options.AddPolicy("Query", builder => builder.SetVaryByQuery("culture"));
options.AddPolicy("NoCache", builder => builder.NoCache());
options.AddPolicy("NoLock", builder => builder.SetLocking(false));
});
A minimális API-alkalmazások esetében az egyik alternatíva a(z) MapGroup
hívása:
var blog = app.MapGroup("blog")
.CacheOutput(builder => builder.Tag("tag-blog"));
blog.MapGet("/", Gravatar.WriteGravatar);
blog.MapGet("/post/{id}", Gravatar.WriteGravatar);
Az előző címke-hozzárendelési példákban mindkét végpontot azonosítja a tag-blog
címke. Ezután az adott címkére hivatkozó egyetlen utasítással kiürítheti a végpontok gyorsítótár-bejegyzéseit:
app.MapPost("/purge/{tag}", async (IOutputCacheStore cache, string tag) =>
{
await cache.EvictByTagAsync(tag, default);
});
Ezzel a kóddal egy HTTP POST-kérés elküldése https://localhost:<port>/purge/tag-blog
a végpontok gyorsítótár-bejegyzéseinek kiürítésére szolgál.
Érdemes lehet az összes végpont összes gyorsítótárbejegyzését kiüríteni. Ehhez hozza létre az összes végponthoz egy alapházirendet, az alábbi kód szerint.
builder.Services.AddOutputCache(options =>
{
options.AddBasePolicy(builder => builder
.With(c => c.HttpContext.Request.Path.StartsWithSegments("/blog"))
.Tag("tag-blog"));
options.AddBasePolicy(builder => builder.Tag("tag-all"));
options.AddPolicy("Query", builder => builder.SetVaryByQuery("culture"));
options.AddPolicy("NoCache", builder => builder.NoCache());
options.AddPolicy("NoLock", builder => builder.SetLocking(false));
});
Ez az alapszabályzat lehetővé teszi, hogy a "tag-all" címkével kiürítsen mindent a gyorsítótárból.
Erőforrás-zárolás letiltása
Alapértelmezés szerint az erőforrás-zárolás engedélyezve van a gyorsítótárbélyegzés és a villámgyors csorda kockázatának csökkentése érdekében. További információ: Kimeneti gyorsítótárazás.
Az erőforrás-zárolás letiltásához hívja meg a SetLocking(false) függvényt egy szabályzat létrehozásakor, ahogyan az alábbi példában látható:
builder.Services.AddOutputCache(options =>
{
options.AddBasePolicy(builder => builder
.With(c => c.HttpContext.Request.Path.StartsWithSegments("/blog"))
.Tag("tag-blog"));
options.AddBasePolicy(builder => builder.Tag("tag-all"));
options.AddPolicy("Query", builder => builder.SetVaryByQuery("culture"));
options.AddPolicy("NoCache", builder => builder.NoCache());
options.AddPolicy("NoLock", builder => builder.SetLocking(false));
});
Az alábbi példa egy minimális API-alkalmazás végpontjánál a zárolás nélküli szabályzatot választja:
app.MapGet("/nolock", Gravatar.WriteGravatar)
.CacheOutput("NoLock");
Egy vezérlőalapú API-ban az attribútum használatával válassza ki a szabályzatot:
[ApiController]
[Route("/[controller]")]
[OutputCache(PolicyName = "NoLock")]
public class NoLockController : ControllerBase
{
public async Task GetAsync()
{
await Gravatar.WriteGravatar(HttpContext);
}
}
Korlátok
Az alábbi tulajdonságok OutputCacheOptions lehetővé teszik az összes végpontra vonatkozó korlátok konfigurálását:
- SizeLimit - A gyorsítótár tárterületének maximális mérete. Ha eléri ezt a korlátot, a rendszer nem gyorsítótárazza az új válaszokat, amíg a régebbi bejegyzések ki nem kerülnek. Az alapértelmezett érték 100 MB.
- MaximumBodySize - Ha a válasz törzse túllépi ezt a korlátot, nem kerül gyorsítótárazásra. Az alapértelmezett érték 64 MB.
- DefaultExpirationTimeSpan – A szabályzat által nem megadott lejárati idő. Az alapértelmezett érték 60 másodperc.
Gyorsítótár-tároló
IOutputCacheStore tárolásra szolgál. Alapértelmezés szerint a következővel használják: MemoryCache. A gyorsítótárazott válaszok tárolása folyamatban történik, így minden kiszolgáló külön gyorsítótárral rendelkezik, amely a kiszolgálói folyamat újraindításakor elveszik.
Redis Cache
Másik lehetőség a Redis Cache használata. A Redis Cache konzisztenciát biztosít a kiszolgálócsomópontok között egy megosztott gyorsítótáron keresztül, amely túllépi az egyes kiszolgálói folyamatokat. Redis használata kimeneti gyorsítótárként:
Telepítse a Microsoft.AspNetCore.OutputCaching.StackExchangeRedis NuGet csomagot.
Hívja meg
builder.Services.AddStackExchangeRedisOutputCache
(nemAddStackExchangeRedisCache
), és adjon meg egy Redis-kiszolgálóra mutató kapcsolati sztringet.Például:
builder.Services.AddStackExchangeRedisOutputCache(options => { options.Configuration = builder.Configuration.GetConnectionString("MyRedisConStr"); options.InstanceName = "SampleInstance"; }); builder.Services.AddOutputCache(options => { options.AddBasePolicy(builder => builder.Expire(TimeSpan.FromSeconds(10))); });
-
options.Configuration
- Kapcsolati lánc egy helyszíni Redis-kiszolgálóhoz vagy egy üzemeltetett ajánlathoz, például az Azure Cache for Redishez. Például az Azure Cache for Redis esetében<instance_name>.redis.cache.windows.net:6380,password=,pw,ssl=True,abortConnect=False
. -
options.InstanceName
– Nem kötelező, egy logikai partíciót ad meg a gyorsítótárhoz.
A konfigurációs beállítások megegyeznek a Redis-alapú elosztott gyorsítótárazási lehetőségekkel.
-
IDistributedCache
nem ajánlott
Nem javasoljuk IDistributedCache kimeneti gyorsítótárazással való használatát.
IDistributedCache
nem rendelkezik atomi jellemzőkkel, amelyek a címkézéshez szükségesek. Javasoljuk, hogy használja a Redis beépített támogatását, vagy hozzon létre egyéni IOutputCacheStore implementációkat a mögöttes tárolási mechanizmus közvetlen függőségeinek használatával.
Lásd még
Ez a cikk bemutatja, hogyan konfigurálhatja a kimeneti gyorsítótárazási köztes szoftvereket egy ASP.NET Core-alkalmazásban. A kimeneti gyorsítótárazásról a Kimeneti gyorsítótárazás című témakörben olvashat bővebben.
A kimeneti gyorsítótárazási köztes szoftver az ASP.NET Core-alkalmazások minden típusában használható: Minimal API, Web API vezérlőkkel, MVC és Razor Pages. A mintaalkalmazás egy minimális API, de a többi alkalmazástípus is támogatja az általa illusztrált gyorsítótárazási funkciókat.
Köztes szoftver hozzáadása az alkalmazáshoz
Adja hozzá a kimeneti gyorsítótárazási middleware-t a szolgáltatásgyűjteményhez a AddOutputCache hívásával.
Adja hozzá a köztes szoftvert a kérésfeldolgozó folyamathoz hívással UseOutputCache.
Megjegyzés:
- A CORS köztes szoftvereket használó alkalmazásokban a
UseOutputCache
függvényt a UseCors után kell meghívni. - A Pages alkalmazásokban és a vezérlőkkel rendelkező alkalmazásokban a Razor meghívását a
UseOutputCache
után kell elvégezni. - A
AddOutputCache
ésUseOutputCache
hívása nem indítja el a gyorsítótárazási viselkedést, hanem elérhetővé teszi a gyorsítótárazást. A gyorsítótárazási válaszadatokat az alábbi szakaszokban látható módon kell konfigurálni.
Egy végpont vagy lap konfigurálása
Minimális API-alkalmazások esetén konfiguráljon egy végpontot gyorsítótárazásra a CacheOutput
hívásával vagy az [OutputCache]
attribútum alkalmazásával, ahogy az alábbi példák mutatják.
app.MapGet("/cached", Gravatar.WriteGravatar).CacheOutput();
app.MapGet("/attribute", [OutputCache] (context) =>
Gravatar.WriteGravatar(context));
Vezérlőkkel rendelkező alkalmazások esetén alkalmazza a [OutputCache]
attribútumot a műveletmetódusra. A Razor Pages alkalmazások esetében alkalmazza az attribútumot az Razor oldal osztályára.
Több végpont vagy lap konfigurálása
Hozzon létre szabályzatokat, amelyek híváskor több végpontra vonatkozó gyorsítótárazási konfigurációt adnak megAddOutputCache
. A szabályzatok kiválaszthatók adott végpontokhoz, míg az alapszabályzatok alapértelmezett gyorsítótárazási konfigurációt biztosítanak a végpontok gyűjteményéhez.
Az alábbi kiemelt kód az alkalmazás összes végpontjának gyorsítótárazását konfigurálja 10 másodperces lejárati idővel. Ha nincs megadva lejárati idő, az alapértelmezés szerint egy perc.
builder.Services.AddOutputCache(options =>
{
options.AddBasePolicy(builder =>
builder.Expire(TimeSpan.FromSeconds(10)));
options.AddPolicy("Expire20", builder =>
builder.Expire(TimeSpan.FromSeconds(20)));
options.AddPolicy("Expire30", builder =>
builder.Expire(TimeSpan.FromSeconds(30)));
});
Az alábbi kiemelt kód két szabályzatot hoz létre, amelyek mindegyike eltérő lejárati időt ad meg. A kijelölt végpontok használhatják a 20 másodperces lejáratot, mások pedig a 30 másodperces lejáratot.
builder.Services.AddOutputCache(options =>
{
options.AddBasePolicy(builder =>
builder.Expire(TimeSpan.FromSeconds(10)));
options.AddPolicy("Expire20", builder =>
builder.Expire(TimeSpan.FromSeconds(20)));
options.AddPolicy("Expire30", builder =>
builder.Expire(TimeSpan.FromSeconds(30)));
});
A metódus meghívásakor CacheOutput
vagy az [OutputCache]
attribútum használatakor kiválaszthatja a végponthoz tartozó szabályzatot:
app.MapGet("/20", Gravatar.WriteGravatar).CacheOutput("Expire20");
app.MapGet("/30", [OutputCache(PolicyName = "Expire30")] (context) =>
Gravatar.WriteGravatar(context));
Vezérlőkkel rendelkező alkalmazások esetén alkalmazza a [OutputCache]
attribútumot a műveletmetódusra. A Razor Pages alkalmazások esetében alkalmazza az attribútumot az Razor oldal osztályára.
Alapértelmezett kimeneti gyorsítótárazási szabályzat
Alapértelmezés szerint a kimeneti gyorsítótárazás a következő szabályokat követi:
- A rendszer csak a HTTP 200-válaszokat gyorsítótárazza.
- Csak a HTTP GET vagy a HEAD kérések gyorsítótárazva vannak.
- Olyan válaszok, amelyek cookie-kat állítanak be, nem kerülnek gyorsítótárazásra.
- A hitelesített kérelmekre adott válaszok nem gyorsítótárazva lesznek.
Az alábbi kód az összes alapértelmezett gyorsítótárazási szabályt alkalmazza az alkalmazás összes végpontjára:
builder.Services.AddOutputCache(options =>
{
options.AddBasePolicy(builder => builder.Cache());
});
Az alapértelmezett szabályzat felülbírálása
Az alábbi kód bemutatja, hogyan bírálhatja felül az alapértelmezett szabályokat. Az alábbi egyéni szabályzatkód kiemelt sorai lehetővé teszik a HTTP POST metódusok és a HTTP 301-válaszok gyorsítótárazását:
using Microsoft.AspNetCore.OutputCaching;
using Microsoft.Extensions.Primitives;
namespace OCMinimal;
public sealed class MyCustomPolicy : IOutputCachePolicy
{
public static readonly MyCustomPolicy Instance = new();
private MyCustomPolicy()
{
}
ValueTask IOutputCachePolicy.CacheRequestAsync(
OutputCacheContext context,
CancellationToken cancellationToken)
{
var attemptOutputCaching = AttemptOutputCaching(context);
context.EnableOutputCaching = true;
context.AllowCacheLookup = attemptOutputCaching;
context.AllowCacheStorage = attemptOutputCaching;
context.AllowLocking = true;
// Vary by any query by default
context.CacheVaryByRules.QueryKeys = "*";
return ValueTask.CompletedTask;
}
ValueTask IOutputCachePolicy.ServeFromCacheAsync
(OutputCacheContext context, CancellationToken cancellationToken)
{
return ValueTask.CompletedTask;
}
ValueTask IOutputCachePolicy.ServeResponseAsync
(OutputCacheContext context, CancellationToken cancellationToken)
{
var response = context.HttpContext.Response;
// Verify existence of cookie headers
if (!StringValues.IsNullOrEmpty(response.Headers.SetCookie))
{
context.AllowCacheStorage = false;
return ValueTask.CompletedTask;
}
// Check response code
if (response.StatusCode != StatusCodes.Status200OK &&
response.StatusCode != StatusCodes.Status301MovedPermanently)
{
context.AllowCacheStorage = false;
return ValueTask.CompletedTask;
}
return ValueTask.CompletedTask;
}
private static bool AttemptOutputCaching(OutputCacheContext context)
{
// Check if the current request fulfills the requirements
// to be cached
var request = context.HttpContext.Request;
// Verify the method
if (!HttpMethods.IsGet(request.Method) &&
!HttpMethods.IsHead(request.Method) &&
!HttpMethods.IsPost(request.Method))
{
return false;
}
// Verify existence of authorization headers
if (!StringValues.IsNullOrEmpty(request.Headers.Authorization) ||
request.HttpContext.User?.Identity?.IsAuthenticated == true)
{
return false;
}
return true;
}
}
Az egyéni szabályzat használatához hozzon létre egy nevesített szabályzatot:
builder.Services.AddOutputCache(options =>
{
options.AddPolicy("CachePost", MyCustomPolicy.Instance);
});
És válassza ki a megnevezett szabályzatot a végponthoz:
app.MapPost("/cachedpost", Gravatar.WriteGravatar)
.CacheOutput("CachePost");
Alternatív alapértelmezett szabályzat felülbírálása
Alternatívaként használja a Függőséginjektálást (DI) egy példány inicializálásához, a következő módosításokkal az egyéni házirend osztályában:
- Magánkonstruktor helyett nyilvános konstruktor.
- Törölje a tulajdonságot
Instance
az egyéni szabályzatosztályból.
Például:
public sealed class MyCustomPolicy2 : IOutputCachePolicy
{
public MyCustomPolicy2()
{
}
Az osztály többi része megegyezik a korábban láthatóval. Adja hozzá az egyéni szabályzatot az alábbi példában látható módon:
builder.Services.AddOutputCache(options =>
{
options.AddPolicy("CachePost", builder =>
builder.AddPolicy<MyCustomPolicy2>(), true);
});
Az előző kód a DI használatával hozza létre az egyéni szabályzatosztály példányát. A konstruktorban lévő nyilvános argumentumok feloldódnak.
Ha egyéni szabályzatot használ alapházirendként, ne hívjon OutputCache()
meg (argumentumok nélkül) olyan végpontot, amelyre az alapházirendnek vonatkoznia kell. A hívás OutputCache()
hozzáadja az alapértelmezett szabályzatot a végponthoz.
A gyorsítótárkulcs megadása
Alapértelmezés szerint az URL-cím minden része a gyorsítótár-bejegyzés kulcsává válik, azaz a séma, a gazdagép, a port, az elérési út és a lekérdezési sztring. Előfordulhat azonban, hogy explicit módon szeretné szabályozni a gyorsítótárkulcsot. Tegyük fel például, hogy van egy végpontja, amely csak a culture
lekérdezési sztring minden egyedi értékére ad vissza egyedi választ. Az URL más részeinek, például más lekérdezési sztringeknek a variációja nem eredményezhet különböző gyorsítótár-bejegyzéseket. Ezeket a szabályokat megadhatja egy szabályzatban, ahogyan az a következő kiemelt kódban is látható:
builder.Services.AddOutputCache(options =>
{
options.AddBasePolicy(builder => builder
.With(c => c.HttpContext.Request.Path.StartsWithSegments("/blog"))
.Tag("tag-blog"));
options.AddBasePolicy(builder => builder.Tag("tag-all"));
options.AddPolicy("Query", builder => builder.SetVaryByQuery("culture"));
options.AddPolicy("NoCache", builder => builder.NoCache());
options.AddPolicy("NoLock", builder => builder.SetLocking(false));
});
Ezután kiválaszthatja a VaryByQuery
szabályzatot a végponthoz.
app.MapGet("/query", Gravatar.WriteGravatar).CacheOutput("Query");
Íme néhány lehetőség a gyorsítótárkulcs vezérlésére:
SetVaryByQuery – Adjon meg egy vagy több lekérdezési sztringnevet, amely hozzáadható a gyorsítótárkulcshoz.
SetVaryByHeader – Adjon meg egy vagy több HTTP-fejlécet, amely hozzáadható a gyorsítótárkulcshoz.
VaryByValue– Adja meg a gyorsítótárkulcshoz hozzáadni kívánt értéket. Az alábbi példa egy értéket használ, amely azt jelzi, hogy a kiszolgáló aktuális ideje másodpercben páratlan vagy páros. Új válasz csak akkor jön létre, ha a másodpercek száma páratlanról párosra vagy párosra megy.
app.MapGet("/varybyvalue", Gravatar.WriteGravatar) .CacheOutput(c => c.VaryByValue((context) => new KeyValuePair<string, string>( "time", (DateTime.Now.Second % 2) .ToString(CultureInfo.InvariantCulture))));
A OutputCacheOptions.UseCaseSensitivePaths használatával megadhatja, hogy a kulcs elérési útja kis- és nagybetű érzékeny. Az alapértelmezett érzéketlen a kis- és nagybetűkre.
További lehetőségekért tekintse meg az OutputCachePolicyBuilder osztályt.
Gyorsítótár-újraértékelés
A gyorsítótár-újraértékelés azt jelenti, hogy a kiszolgáló a teljes válasz törzse helyett EGY HTTP-állapotkódot tud visszaadni 304 Not Modified
. Ez az állapotkód tájékoztatja az ügyfelet, hogy a kérésre adott válasz nem változik, mint amit az ügyfél korábban kapott.
Az alábbi kód egy Etag
fejléc használatát mutatja be a gyorsítótár újraértékelésének engedélyezéséhez. Ha az ügyfél egy If-None-Match
korábbi válasz etagértékével rendelkező fejlécet küld, és a gyorsítótár-bejegyzés friss, a kiszolgáló a teljes válasz helyett a 304 Nem módosult értéket adja vissza:
app.MapGet("/etag", async (context) =>
{
var etag = $"\"{Guid.NewGuid():n}\"";
context.Response.Headers.ETag = etag;
await Gravatar.WriteGravatar(context);
}).CacheOutput();
A gyorsítótár-újraértékelés másik módja az, hogy összehasonlítjuk a gyorsítótár-bejegyzés létrehozásának dátumát az ügyfél által kért dátummal. A kérelem fejlécének If-Modified-Since
megadásakor a kimeneti gyorsítótárazás 304-et ad vissza, ha a gyorsítótárazott bejegyzés régebbi, és nem járt le.
A gyorsítótár újraértékelése automatikusan történik az ügyféltől érkező fejlécek hatására. Ennek a viselkedésnek az engedélyezéséhez nincs szükség speciális konfigurációra a kiszolgálón, a kimeneti gyorsítótárazás engedélyezésén kívül.
Gyorsítótár bejegyzések eltávolítása címkék használatával
Címkék használatával azonosíthatja a végpontok egy csoportját, és kizárhatja a csoport összes gyorsítótár-bejegyzését. Az alábbi kód például létrehoz egy végpontpárt, amelynek URL-címei "blog"-tal kezdődnek, és címkézik őket "tag-blog":
app.MapGet("/blog", Gravatar.WriteGravatar)
.CacheOutput(builder => builder.Tag("tag-blog"));
app.MapGet("/blog/post/{id}", Gravatar.WriteGravatar)
.CacheOutput(builder => builder.Tag("tag-blog"));
Ugyanazon végpontpár címkéinek hozzárendelésének másik módja egy olyan alapházirend definiálása, amely a következővel blog
kezdődő végpontokra vonatkozik:
builder.Services.AddOutputCache(options =>
{
options.AddBasePolicy(builder => builder
.With(c => c.HttpContext.Request.Path.StartsWithSegments("/blog"))
.Tag("tag-blog"));
options.AddBasePolicy(builder => builder.Tag("tag-all"));
options.AddPolicy("Query", builder => builder.SetVaryByQuery("culture"));
options.AddPolicy("NoCache", builder => builder.NoCache());
options.AddPolicy("NoLock", builder => builder.SetLocking(false));
});
Egy másik alternatíva a következő módon hívni MapGroup
:
var blog = app.MapGroup("blog")
.CacheOutput(builder => builder.Tag("tag-blog"));
blog.MapGet("/", Gravatar.WriteGravatar);
blog.MapGet("/post/{id}", Gravatar.WriteGravatar);
Az előző címke-hozzárendelési példákban mindkét végpontot azonosítja a tag-blog
címke. Ezután az adott címkére hivatkozó egyetlen utasítással kiürítheti a végpontok gyorsítótár-bejegyzéseit:
app.MapPost("/purge/{tag}", async (IOutputCacheStore cache, string tag) =>
{
await cache.EvictByTagAsync(tag, default);
});
Ezzel a kóddal, egy HTTP POST-kérés, amelyet a(z) https://localhost:<port>/purge/tag-blog
címre küldünk, kiüríti a gyorsítótár bejegyzéseit ezekről a végpontokról.
Érdemes lehet az összes végpont összes gyorsítótárbejegyzését kiüríteni. Ehhez hozza létre az összes végponthoz egy alapházirendet, az alábbi kód szerint.
builder.Services.AddOutputCache(options =>
{
options.AddBasePolicy(builder => builder
.With(c => c.HttpContext.Request.Path.StartsWithSegments("/blog"))
.Tag("tag-blog"));
options.AddBasePolicy(builder => builder.Tag("tag-all"));
options.AddPolicy("Query", builder => builder.SetVaryByQuery("culture"));
options.AddPolicy("NoCache", builder => builder.NoCache());
options.AddPolicy("NoLock", builder => builder.SetLocking(false));
});
Ez az alapszabályzat lehetővé teszi, hogy a "tag-all" címkével kiürítsen mindent a gyorsítótárból.
Erőforrás-zárolás letiltása
Alapértelmezés szerint az erőforrás-zárolás engedélyezve van a gyorsítótárbélyegzés és a villámgyors csorda kockázatának csökkentése érdekében. További információ: Kimeneti gyorsítótárazás.
Az erőforrás-zárolás letiltásához hívja meg a SetLocking(false) függvényt egy szabályzat létrehozásakor, ahogyan az alábbi példában látható:
builder.Services.AddOutputCache(options =>
{
options.AddBasePolicy(builder => builder
.With(c => c.HttpContext.Request.Path.StartsWithSegments("/blog"))
.Tag("tag-blog"));
options.AddBasePolicy(builder => builder.Tag("tag-all"));
options.AddPolicy("Query", builder => builder.SetVaryByQuery("culture"));
options.AddPolicy("NoCache", builder => builder.NoCache());
options.AddPolicy("NoLock", builder => builder.SetLocking(false));
});
Az alábbi példa egy végpont nem zárolási szabályzatát választja ki:
app.MapGet("/nolock", Gravatar.WriteGravatar)
.CacheOutput("NoLock");
Korlátok
Az alábbi tulajdonságok OutputCacheOptions lehetővé teszik az összes végpontra vonatkozó korlátok konfigurálását:
- SizeLimit - A gyorsítótár tárterületének maximális mérete. A korlát elérésekor a rendszer nem gyorsítótárazza az új válaszokat, amíg a régebbi bejegyzések ki nem kerülnek. Az alapértelmezett érték 100 MB.
- MaximumBodySize - Ha a válasz törzse túllépi ezt a korlátot, nem kerül gyorsítótárazásra. Az alapértelmezett érték 64 MB.
- DefaultExpirationTimeSpan – A szabályzat által nem megadott lejárati idő. Az alapértelmezett érték 60 másodperc.
Gyorsítótár-tároló
IOutputCacheStore tárolásra szolgál. Alapértelmezés szerint a következővel használják: MemoryCache. Nem javasoljuk IDistributedCache kimeneti gyorsítótárazással való használatát.
IDistributedCache
nem rendelkezik atomi jellemzőkkel, amelyek a címkézéshez szükségesek. Javasoljuk, hogy egyéni IOutputCacheStore implementációkat hozzon létre az alapul szolgáló tárolási mechanizmus közvetlen függőségei, például a Redis használatával. Vagy használja a Redis Cache beépített támogatását a .NET 8-ban.