ASP.NET Core API & Blazor 實作快取機制提升效能
前言
🔗最近的專案,因為有大量縮圖與計算,導致每次畫面呈現的速度,都達不到想要的水準,除了本身代碼與 T-SQL 的優化、還可以藉由懶加載 ( Lazy loading ) 等,達到提升資料讀取速度的效果。
除了這些方式,還能藉由快取,達到更好的性能,此文章紀錄使用 Blazor WASM 架構與 ASP.NET Core API 建立快取機制。
快取機制
🔗說到快取(緩存),可以理解為使用或是讀取預先存放好的資料,因為不用重新從資料庫或是伺服器取得檔案,速度可以有效提升,降低網站負荷。
如果網站為靜態網站,或是有大量靜態資源的需求,若每次使用者進入網站,都需要讀取一次資源,那勢必會有流暢度的問題,這時若使用 CDN(Content Delivery Network)服務,藉由分布於全球的伺服器節點組成的網路,就能有效提升靜態資源的傳輸速度與性能,這其中就有用到快取的技術,藉由預先存放靜態資源在各地,達到高效傳輸。
而若是在後端 API 的部分,也能使用類似的快取機制達到高效傳輸,預先存放資料的位置則是存放在記憶體中。本篇將介紹如何使用 MemoryCache
類進行緩存,若是大型網站或是分散式系統可使用 IDistributedCache
類等之後有機會再研究。
使用時機
🔗若要使用 MemoryCache
類進行緩存,因資料存放於記憶體,若應用程式關閉或重啟、系統故障,或是系統本身對於內存進行管理與優化,都會造成存放的資料消失。所以快取並不建議存放重要資料,或是頻繁變動的資料以致網站內容資訊不正確。
以本篇為例,專案網站在首頁會顯示封面圖,而因為封面圖並不會頻繁更新,且資料也已儲存在資料庫與AWS S3,所以預先儲存在快取,就是一個不錯的方式以提升使用者載入首頁的速度。
代碼
🔗建立快取
🔗架構不管是 Blazor WASM 還是 一般的 Web API 都是對控制器內的 API 進行修改。 代碼如下:
C#using Microsoft.Extensions.Caching.Memory;
namespace BlazorApp.Server.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class StorageController : ControllerBase
{
private readonly IStorageService _storageService;
private readonly IMemoryCache _cache;
public StorageController(IStorageService storageService, IMemoryCache memoryCache)
{
_storageService = storageService;
_cache = memoryCache;
}
[HttpGet("logo/admin-no-cache")]
public async Task<List<S3FileInfo>> GetLogoFileNoCache()
{
List<S3FileInfo> FileInfo = await _storageService.GetFileByKeyAsync();
return FileInfo;
}
[HttpGet("logo")]
public async Task<List<S3FileInfo>> GetLogoFile()
{
string cacheKey = "logo";
if (!_cache.TryGetValue<List<S3FileInfo>>(cacheKey, out List<S3FileInfo> cachedData))
{
List<S3FileInfo> FileInfo = await _storageService.GetFileByKeyAsync();
cachedData = FileInfo;
_cache.Set(cacheKey, cachedData, TimeSpan.FromHours(24));
}
return cachedData;
}
}
}
有兩支 API,一支為logo/admin-no-cache
為管理員使用,針對管理員需當下確認資料正確性,為無快取版本。
另一支為logo
,供首頁載入時使用,邏輯為設定快取的Key為logo
,每次呼叫時,需確認快取是否有包含Key為logo
的資料,
若有則取用,若無則重新取得資料。
_cache.Set(cacheKey, cachedData, TimeSpan.FromHours(24));
在取得資料後,儲存資料至快取,並設定24小時候過期。也就是說每過了24小時,快取就會消失,之後的第一個讀取網站的人,載入速度就會回歸正常,因為必須重新讀取資料,而之後的每位使用者就還是一樣的高效快速。😎
移除快取
🔗有時也有清除快取的需求,例如資料更新後清除快取以讓使用者看到即時內容。
移除特定快取代碼:
C#_cache.Remove("logo");
取得快取列表
🔗網站有快取之後,為了部分即時更新的資料還是得提供管理者清除快取功能,可以藉由取得目前記憶體儲存的快取 key 列表後,再配合上方移除快取進一步刪除。
C#[HttpGet("cache")]
public async Task<List<string>> GetCacheList()
{
var field = typeof(MemoryCache).GetProperty("EntriesCollection", BindingFlags.NonPublic | BindingFlags.Instance);
var collection = field.GetValue(_cache) as ICollection;
var items = new List<string>();
if (collection != null)
foreach (var item in collection)
{
var methodInfo = item.GetType().GetProperty("Key");
var val = methodInfo.GetValue(item);
items.Add(val.ToString());
}
return items;
}
結論
🔗以上就是如何使用 ASP.NET Core 實作內存快取機制,個人是把需要快取的資料分為兩支 API,比較好分類,實際可依照需求增加判斷決定是否取得快取資料或是實際資料。網站若是使用雲端資料庫或是 S3 等服務,如果能好好善用快取,相信可以減少許多傳輸資料的花費呢。😎
Alvin
軟體工程師,喜歡金融知識、健康觀念、心理哲學、自助旅遊與系統設計。
相關文章
留言區 (0)
尚無留言