练习 - 在 Redis 中缓存数据
在本练习中,你将为你的户外装备零售商将缓存添加到部分完成的云原生应用。 你要将 Redis 添加到 AppHost 项目,然后在 WebApp 项目中实现输出缓存,并在 Catalog.API 项目中实现分布式缓存。
安装先决条件
.NET Aspire 的先决条件包括:
- .NET 8
- Visual Studio 2022 预览版
- Docker Desktop
- Visual Studio 中的 .NET Aspire 工作负载
如果已安装这些包,则可以直接跳到开始使用 Redis 缓存的步骤。
安装 .NET 8
单击此 .NET 8 链接,然后根据操作系统选择正确的安装程序。 例如,如果使用的是 Windows 11 和新式处理器,请选择适用于 Windows 的 x64 .NET 8 SDK。
下载完成后,运行安装程序并按照说明操作。 在终端窗口中,运行以下命令以验证安装是否成功:
dotnet --version
应会看到所安装的 .NET SDK 版本号。 例如:
8.0.300-preview.24203.14
安装 Visual Studio 2022 预览版
单击此 Visual Studio 2022 预览版链接,然后选择“下载预览版”。 下载完成后,运行安装程序并按照说明操作。
安装 Docker Desktop
单击此 Docker Desktop 链接,然后根据操作系统选择正确的安装程序。 下载完成后,运行安装程序并按照说明操作。 为了获得最佳性能和兼容性,请使用 WSL 2 后端。
打开 Docker Desktop 应用程序并接受服务协议。
在 Visual Studio 中安装 .NET Aspire 工作负载
使用 .NET CLI 安装 .NET Aspire 工作负载:
打开终端。
使用以下命令更新 .NET 工作负载:
dotnet workload update
应会看到一条消息,指出工作负载已成功更新。
No workloads installed for this feature band. To update workloads installed with earlier SDK versions, include the --from-previous-sdk option. Updated advertising manifest microsoft.net.sdk.ios. Updated advertising manifest microsoft.net.workload.mono.toolchain.net6. Updated advertising manifest microsoft.net.sdk.android. Updated advertising manifest microsoft.net.workload.emscripten.net7. Updated advertising manifest microsoft.net.workload.emscripten.net6. Updated advertising manifest microsoft.net.sdk.macos. Updated advertising manifest microsoft.net.workload.emscripten.current. Updated advertising manifest microsoft.net.workload.mono.toolchain.current. Updated advertising manifest microsoft.net.sdk.maui. Updated advertising manifest microsoft.net.workload.mono.toolchain.net7. Updated advertising manifest microsoft.net.sdk.maccatalyst. Updated advertising manifest microsoft.net.sdk.tvos. Updated advertising manifest microsoft.net.sdk.aspire. No workloads installed for this feature band. To update workloads installed with earlier SDK versions, include the --from-previous-sdk option. Successfully updated workload(s): .
使用以下命令安装 .NET Aspire 工作负载:
dotnet workload install aspire
应会看到一条消息,指出 Aspire 工作负载已安装。
Installing Aspire.Hosting.Sdk.Msi.x64 ...... Done Installing Aspire.ProjectTemplates.Msi.x64 ..... Done Installing Aspire.Hosting.Orchestration.win-x64.Msi.x64 ............. Done Installing Aspire.Hosting.Msi.x64 ..... Done Installing Aspire.Dashboard.Sdk.win-x64.Msi.x64 ....... Done Successfully installed workload(s) aspire.
使用以下命令验证是否安装了 .NET Aspire 工作负载:
dotnet workload list
你应会看到
aspire
工作负载的详细信息。Installed Workload Id Manifest Version Installation Source --------------------------------------------------------------------------------------------- aspire 8.0.0/8.0.100 SDK 8.0.300-preview.24203, VS 17.10.34902.84 Use `dotnet workload search` to find additional workloads to install.
克隆和修改示例应用
让我们使用 git
来获取使用 .NET Aspire 生成的示例应用。 该应用尚未设置缓存:
在命令行中,浏览到你选择的、可在其中处理代码的文件夹。
执行以下命令克隆 Northern Mountains eShop 示例应用程序:
git clone -b aspire-cache https://github.com/MicrosoftDocs/mslearn-aspire-starter
启动 Visual Studio,然后选择“打开项目或解决方案”。
浏览到你克隆了 eShop 的文件夹,打开 start 文件夹并选择 eShop.rediscache.sln 文件,然后选择“打开”。
在“解决方案资源管理器”中,浏览到 WebApp/Components/Pages,然后双击 Catalog.razor。
找到以下代码行:
<SectionContent SectionName="page-header-subtitle">Start the season with the latest in clothing and equipment.</SectionContent>
请使用以下代码替换这一行:
<SectionContent SectionName="page-header-subtitle">Start the season with the latest in clothing and equipment. It's @DateTime.Now</SectionContent>
若要启动应用,请按 F5 或选择“调试”>“开始调试”。
如果出现“启动 Docker Desktop”对话框,请选择“是”。
出现 eShop .NET Aspire 仪表板时,对于 webapp 资源,请选择以下终结点之一:
该终结点显示了 Northern Mountains 主页。 包括服务器上的时间:
按 F5 刷新页面。 由于页面没有缓存,因此每次刷新时,只要秒数发生变化,显示的时间就会改变。
切换到显示 .NET Aspire 仪表板的浏览器选项卡,然后在左侧导航菜单中选择“跟踪”。
名为“webapp:GET /”的跟踪是主页的请求。 记下这些请求的典型“持续时间”,然后在其中一个请求中选择“详细信息”列中的“视图”:
在时间线视图中,请注意,webapp 会调用多个微服务来构造响应。
关闭 Northern Mountains 主页和 .NET Aspire 仪表板。
在 Visual Studio 中,若要停止调试,请按 SHIFT - F5 或选择“调试 > 停止调试”。
添加缓存支持服务
现在,你已了解主页如何在不缓存的情况下运行,让我们添加输出缓存,看看它是否会提高响应能力。 首先,将输出缓存组件添加到 AppHost 项目:
在 Visual Studio 的“解决方案资源管理器”中,右键单击 eShop.AppHost 项目,选择“添加”,然后选择“.NET Aspire 包”。
在搜索文本框中,在现有文本末尾键入“Redis”。
选择 Aspire.Hosting.Redis 包。
在“版本”列表中,选择最新的“8.0.0”版本,然后选择“安装”。
如果出现“预览更改”对话框,请选择“应用”。
在“许可接受”对话框中,选择“我接受”。
在“解决方案资源管理器”中,展开 AppHost 项目,然后双击 Program.cs。
找到以下代码行:
// Databases var postgres = builder.AddPostgres("postgres").WithPgAdmin(); var catalogDb = postgres.AddDatabase("CatalogDB");
紧跟这些行后,添加以下代码:
// Cache var redis = builder.AddRedis("cache");
找到以下代码行,它会将 Catalog API 项目添加到 .NET Aspire 业务流程:
var catalogApi = builder.AddProject<Catalog_API>("catalog-api") .WithReference(catalogDb);
若要将 Redis 缓存传递到 Catalog API 项目,请将该代码替换为以下行:
var catalogApi = builder.AddProject<Catalog_API>("catalog-api") .WithReference(catalogDb) .WithReference(redis);
注意
我们将使用 Catalog API 中的缓存来执行分布式缓存。
找到以下代码行,它会将 WebApp 项目添加到 .NET Aspire 业务流程:
builder.AddProject<WebApp>("webapp") .WithReference(catalogApi);
若要将 Redis 缓存传递到 WebApp 项目,请将该代码替换为以下行:
builder.AddProject<WebApp>("webapp") .WithReference(catalogApi) .WithReference(redis);
注意
我们将使用 WebApp 中的缓存来执行输出缓存。
若要保存 Program.cs 文件,请按 CTRL - S 或选择“文件 > 保存 Program.cs”。
在 WebApp 项目中使用输出缓存
现在,让我们使用 WebApp 项目中的 Redis 缓存来缓存主页输出:
在 Visual Studio 的“解决方案资源管理器”中,右键单击 WebApp 项目,选择“添加”,然后选择“.NET Aspire 包”。
在搜索文本框中,在现有文本末尾键入“Redis”。
选择 Aspire.StackExchange.Redis.OutputCaching 包。
在“版本”列表中,选择最新的“8.0.0”版本,然后选择“安装”。
如果出现“预览更改”对话框,请选择“应用”。
在“许可接受”对话框中,选择“我接受”。
安装完成后,在“解决方案资源管理器”中展开 WebApp,然后双击 Program.cs。
找到以下代码行:
var builder = WebApplication.CreateBuilder(args);
紧接在该行之后,若要将输出缓存添加到项目,请添加以下代码:
builder.AddRedisOutputCache("cache");
找到以下代码行:
var app = builder.Build();
紧接在该行之后,若要将缓存中间件添加到请求管道,请添加以下代码:
app.UseOutputCache();
在“解决方案资源管理器”中,展开“WebApp > 组件 > 页面”,然后双击 Catalog.razor。
找到以下代码行:
@attribute [StreamRendering]
紧接在该行之后,若要缓存主页,请添加以下代码:
@attribute [Microsoft.AspNetCore.OutputCaching.OutputCache(Duration = 10)]
测试输出缓存
输出缓存现已在 Northern Mountains 主页中实现。 我们来检验一下:
在 Visual Studio 中,若要启动应用,请按 F5 或选择“调试 > 开始调试”。
出现 eShop .NET Aspire 仪表板时,对于 webapp 资源,请选择以下终结点之一:
该终结点显示了 Northern Mountains 主页,包括服务器上的时间。
按 F5 刷新页面。 由于页面缓存时间为 10 秒,只有在缓存请求后超过 10 秒时,显示的时间才会发生变化。
切换到显示 .NET Aspire 仪表板的浏览器选项卡,然后在左侧导航菜单中选择“跟踪”。
名为“webapp:GET /”的跟踪是主页的请求。 对主页的某些请求无法从缓存中满足,其时间与你之前记录的持续时间类似。 但是,从缓存返回的其他请求持续时间要短得多。
对于某个较短的请求,请选择“详细信息”列中的“视图”。 请注意,请求是从 Redis 缓存中检索的:
关闭 Northern Mountains 主页和 .NET Aspire 仪表板。
在 Visual Studio 中,若要停止调试,请按 SHIFT - F5 或选择“调试 > 停止调试”。
使用分布式缓存
我们还可以使用 Redis 在 Catalog.API 项目中执行分布式缓存:
在 Visual Studio 的“解决方案资源管理器”中,右键单击 Catalog.API 项目,选择“添加”,然后选择“.NET Aspire 包”。
在搜索文本框中,在现有文本末尾键入“Redis”。
选择 Aspire.StackExchange.Redis.DistributedCaching 包。
在“版本”列表中,选择最新的“8.0.0”版本,然后选择“安装”。
如果出现“预览更改”对话框,请选择“应用”。
在“许可接受”对话框中,选择“我接受”。
安装完成后,在“解决方案资源管理器”中展开 Catalog.API,然后双击 Program.cs。
找到以下代码行:
var builder = WebApplication.CreateBuilder(args);
紧接在该行之后,若要将输出缓存添加到项目,请添加以下代码:
builder.AddRedisDistributedCache("cache");
在“解决方案资源管理器”中,展开“Catalog.API > Apis”,然后双击“CatalogApi.cs”。
找到以下代码,该代码声明了
GetAllItems
方法:public static async Task<Results<Ok<PaginatedItems<CatalogItem>>, BadRequest<string>>> GetAllItems( [AsParameters] PaginationRequest paginationRequest, [AsParameters] CatalogServices services) {
若要通过依赖项注入获取 Redis 缓存,请修改该代码以向方法添加新参数:
public static async Task<Results<Ok<PaginatedItems<CatalogItem>>, BadRequest<string>>> GetAllItems( [AsParameters] PaginationRequest paginationRequest, [AsParameters] CatalogServices services, IDistributedCache cache) {
移除
GetAllItems
方法的全部内容,并将其替换为以下代码:var pageSize = paginationRequest.PageSize; var pageIndex = paginationRequest.PageIndex; var totalItems = await services.DbContext.CatalogItems .LongCountAsync(); // Check that there are cached items var cachedItems = await cache.GetAsync("catalogItems"); if (cachedItems is null) { // There are no items in the cache. Get them from the database var itemsOnPage = await services.DbContext.CatalogItems .OrderBy(c => c.Name) .Skip(pageSize * pageIndex) .Take(pageSize) .AsNoTracking() .ToListAsync(); // Store the items in the cache for 10 seconds await cache.SetAsync("catalogItems", Encoding.UTF8.GetBytes(System.Text.Json.JsonSerializer.Serialize(itemsOnPage)), new() { AbsoluteExpiration = DateTime.Now.AddSeconds(10) }); ChangeUriPlaceholder(services.Options.Value, itemsOnPage); return TypedResults.Ok(new PaginatedItems<CatalogItem>(pageIndex, pageSize, totalItems, itemsOnPage)); } else { // There are items in the cache. Deserialize them to display. var itemsOnPage = System.Text.Json.JsonSerializer.Deserialize<List<CatalogItem>>(cachedItems); // Make sure itemsOnPage is not null if (itemsOnPage is null) { itemsOnPage = new List<CatalogItem>(); } ChangeUriPlaceholder(services.Options.Value, itemsOnPage); return TypedResults.Ok(new PaginatedItems<CatalogItem>(pageIndex, pageSize, totalItems, itemsOnPage)); }
测试分布式缓存
分布式缓存现已在 Catalog.API 项目中实现。 我们来检验一下:
在 Visual Studio 中,若要启动应用,请按 F5 或选择“调试 > 开始调试”。
出现 eShop .NET Aspire 仪表板时,对于 catalog-api 资源,请选择终结点:
该终结点显示 Catalog API 微服务的 Swagger 接口。 在 /api/v1/catalog/items 方法旁边,选择 GET。
选择“试用”,然后选择“执行”。 结果会显示在“响应主体”窗口中:
单击“执行”多次以再次调用 API。 只要这些请求在第一个请求后不超过 10 秒,它们就应能从缓存中获取项。
切换到显示 .NET Aspire 仪表板的浏览器选项卡,然后在左侧导航菜单中选择“跟踪”。
名为“catalog-api:GET /api/v1/catalog/items”的跟踪是 Catalog API 的 items 方法的请求。 请注意,该方法的第一个请求需要更长的时间来构建后续请求,API 会从 Redis 缓存中获取项:
关闭 Swagger 页面和 .NET Aspire 仪表板。
在 Visual Studio 中,若要停止调试,请按 SHIFT - F5 或选择“调试 > 停止调试”。