快取
其實也是一種儲存應用程式狀態的方式,因為要花比較多篇幅說明才獨立出一篇。而且官方文件也是不同章節XD
快取
會複製一份資料在快取的儲存機制中,讓取值的速度比原本的來源快,適合擺常使用但不常變動的資料。其實快取
跟 Session
大概有 87% 像,差別是不同執行期間(不同電腦或不同瀏覽器)的快取
會取到同一個值,而 Session
會以存在執行期間的 Cookie 中的識別值來取資料。ASP.NET Core 目前提供三種儲存方式來實作快取:記憶體、資料庫和 Redis,其實跟 Session 一樣啦。
要使用記憶體快取,需要在 Startup.ConfigureServices
中加入:
public void ConfigureServices(IServiceCollection services) {
// ...other services configurations
services.AddMemoryCache();
}
正確設定後,就可以在應用程式中注入 IMemoryCache
來讀寫快取值,快取
的資料類似 Dictionary<object,object>
的結構,以索引鍵和值可以為任何型態。我們可以用 Set
寫值、用 Get
取值或用 GetOrCreate
在索引鍵不存在時寫入並取得預設值:
public class ApplicationStatesController : Controller
{
private readonly IMemoryCache _memoryCache;
public ApplicationStatesController(IMemoryCache memoryCache)
{
_memoryCache = memoryCache;
}
public IActionResult Cache()
{
_memoryCache.Set("string key", "string value");
_memoryCache.Set(2018, 1101);
_memoryCache.GetOrCreate(new object(), entry => DateTime.Now);
return new EmptyResult();
}
}
在寫入快取值時,可以透過 MemoryCacheEntryOptions
類別來做額外設定。
public IActionResult CacheOptions()
{
var cacheValue = DateTime.Now;
// 絕對過期時間:時間到後就會消失
_memoryCache.Set("AbsoluteExpiration", cacheValue,
new MemoryCacheEntryOptions()
.SetAbsoluteExpiration(TimeSpan.FromMinutes(2)));
// 相對過期時間:每次讀取值後會重新計算過期時間
_memoryCache.Set("SlidingExpiration", cacheValue,
new MemoryCacheEntryOptions()
.SetSlidingExpiration(TimeSpan.FromMinutes(2)));
// 優先權:資源吃緊時,會先釋放優先權較低的資料
_memoryCache.Set("Priority", cacheValue,
new MemoryCacheEntryOptions()
.SetPriority(CacheItemPriority.NeverRemove));
// 資料消失時的回呼函式
_memoryCache.Set("PostEvictionCallbacks", cacheValue,
new MemoryCacheEntryOptions()
.RegisterPostEvictionCallback((key, value, reason, state) =>
{
_logger.LogDebug($"快取鍵值: {key} 已消失。原因: {reason}");
}));
return new EmptyResult();
}
當應用程式有需要跨多個伺服器時(例如需要負載平衡),會需要分散式快取來讓每個請求的結果保持一致。在開發階段時,可以使用分散式記憶體快取,但在生產環境時就需要指定實際儲存快取資料的環境了。要使用分散式快取,需要在 Startup.ConfigureServices
中做設定(跟 Session)一樣,使用時需要注入 IDistributedCache
來讀寫快取值:
public void ConfigureServices(IServiceCollection services)
{
services.AddDistributedMemoryCache();
}
public class ApplicationStatesController : Controller
{
private readonly IDistributedCache _distributedCache;
public ApplicationStatesController(IDistributedCache distributedCache)
{
_distributedCache = distributedCache;
}
}
分散式快取中儲存的值需要被轉換成
byte[]
型態。
如果要使用 SqlServer 或 Redis 作為快取儲存的目標,可以參考官方文件:SqlServer、Redis