本文主要介紹了緩存的概念,以及如何在服務器內存中存儲內容。今天的目標是利用IDistributedCache來做一些分布式緩存,這樣我們就可以橫向擴展我們的web應用程序。
在本教程中,我將使用Redis作為緩存。Redis是一個可靠的快速內存緩存,可以存儲多種類型的對象。Redis正在被Twitter, Github, Instagram, Stackoverflow等巨頭使用。
你可以在https://github.com/sahan91/DistributedCacheAspNetCoreRedis找到示例代碼。
這是我們實現后的一個快照。
- 用戶請求一個User對象。
- App server檢查緩存中是否已經有用戶,如果存在則返回對象。
- App server通過HTTP調用來檢索用戶列表。
- Users service將用戶列表返回給App server。
- App server將用戶列表發送到分布式(Redis)緩存。
- App server獲得緩存的版本,直到它過期(TTL)。
- 用戶獲取緩存的User對象。
我們稱其為分布式緩存的主要原因是,它位於應用服務器之外(與傳統的內存緩存相反),如果需要的話,我們可以靈活地水平擴展它(在雲中操作時)。來看看在企業應用程序中是如何有用的。
IDistributedCache接口為我們提供了一組操作緩存的方法。這里總結了幾種不同的方法。
搭建一個示例應用程序
我們將用ASP.NET Core 5創建一個Web MVC應用程序。
dotnet new mvc -n DistributedCachedotnet new slndotnet sln add DistributedCache
讓我們繼續從NuGet添加Redis客戶端包。
dotnet add package Microsoft.Extensions.Caching.StackExchangeRedis --version 5.0.1
創建一個Redis docker容器
假設已經在你的機器上安裝了Docker。這是很方便的,你可以在任何想要開發的時候啟動自己的Redis容器。
docker run --name redis-cache -p 5002:6379 -d redis
使用官方的Redis鏡像,創建一個名為redis-cache的容器,並將容器的6379端口綁定到主機的5002端口。如果你在本地沒有Redis的鏡像,它會從DockerHub獲取它。接下來讓我們驗證docker實例是否啟動並運行。
docker ps -a
現在我們已經有了Redis容器並運行,接下來配置我們的web應用程序。
應用程序配置
因為我們已經添加了所需的NuGet包,我們只需要在應用的DI容器中注冊,並告訴它在哪里可以找到我們的Redis實例。
services.AddStackExchangeRedisCache(options =>{ options.Configuration = Configuration.GetSection("Redis")["ConnectionString"]; });
當我們在服務對象上調用AddStackExchangeRedisCache時,它會在底層通過IDistributedCache接口注冊一個RedisCache類的單例。
services.Add(ServiceDescriptor.Singleton<IDistributedCache, RedisCache>());
因為我們已經在5002端口上啟動並運行了Docker實例,所以我們可以在配置中設置它。
"Redis": { "ConnectionString": "localhost:5002"}
實現
這個功能很簡單,下面是我們要做的:
- 獲取緩存的用戶(如果有的話)並顯示其電子郵件地址
- 用於調用HTTP緩存用戶列表的按鈕
- 清除緩存的按鈕
UI將類似於以下。
讓我們看看程序的入口,HomeController類。
public async Task<IActionResult> Index(){ var users = (await _cacheService.GetCachedUser())?.FirstOrDefault(); return View(users); } public async Task<IActionResult> CacheUserAsync(){ var users = await _usersService.GetUsersAsync(); var cacheEntry = users.First(); return View(nameof(Index), cacheEntry); } public IActionResult CacheRemoveAsync(){ _cacheService.ClearCache(); return RedirectToAction(nameof(Index)); }
這里的代碼很容易解釋,我們在Index、CacheUserAsync和cacheeremoveasync中實現了之前的3個內容。
跳過所有其他管道代碼,並展示我們如何使用Redis緩存獲取和設置值。真正神奇的事情發生在ICacheProvider類中。
在GetFromCache方法中,我們使用給定的鍵(在本例中為_Users)調用GetStringAsync。值得注意的是,在將它返回給調用者之前,我們需要將它反序列化為我們想要的類型。類似地,序列化我們的用戶列表,並將它作為字符串保存在Redis緩存中的_Users鍵下。
public class CacheProvider : ICacheProvider{ private readonly IDistributedCache _cache; public CacheProvider(IDistributedCache cache) { _cache = cache; } public async Task<T> GetFromCache<T>(string key) where T : class { var cachedResponse = await _cache.GetStringAsync(key); return cachedResponse == null ? null : JsonSerializer.Deserialize<T>(cachedResponse); } public async Task SetCache<T>(string key, T value, DistributedCacheEntryOptions options) where T : class { var response = JsonSerializer.Serialize(value); await _cache.SetStringAsync(key, response , options); } public async Task ClearCache(string key) { await _cache.RemoveAsync(key); } }
我們可以連接到容器,打開redis-cli查看里面有什么。
docker exec -it redis-cache redis-cli
進入后,可以發出hgetall _Users命令來檢查緩存中有哪些內容。
結論
在本文中,我們將使用ASP.NET Core提供的IDistributedCache接口,使用Redis作為后台存儲。這種方法可以用來利用Azure Redis緩存等雲服務,用於響應緩存、會話存儲等。
原文鏈接:https://sahansera.dev/distributed-caching-aspnet-core-redis/