Exercício - Armazenar dados em cache no Redis

Concluído

Nesse exercício, você adicionará cache ao aplicativo nativo da nuvem parcialmente concluído para seu revendedor de equipamentos para atividades ao ar livre. Você adicionará o Redis ao projeto AppHost e, em seguida, implementará o cache de saída no projeto WebApp e o cache distribuído no projeto Catalog.API.

Instalar pré-requisitos

Os pré-requisitos para o .NET Aspire são:

  • .NET 8
  • Visualização do Visual Studio 2022
  • Docker Desktop
  • Carga de trabalho do .NET Aspire no Visual Studio

Se você já tiver esses pacotes instalados, poderá avançar para começar a trabalhar com um cache Redis.

Instalar o .NET 8

Siga esse link do .NET 8 e selecione o instalador correto para o seu sistema operacional. Por exemplo, se você estiver usando o Windows 11 e um processador moderno, selecione x64 .NET 8 SDK para Windows.

Após a conclusão do download, execute o instalador e siga as instruções. Em uma janela de terminal, execute o seguinte comando para verificar se a instalação foi bem-sucedida:

dotnet --version

Você deverá ver o número da versão do SDK do .NET instalado. Por exemplo:

8.0.300-preview.24203.14

Instale a versão prévia do Visual Studio 2022

Siga esse link Visual Studio 2022 Preview e selecione Baixar versão prévia. Após a conclusão do download, execute o instalador e siga as instruções.

Instalar o Docker Desktop

Siga esse link Docker Desktop e selecione o instalador correto para o seu sistema operacional. Após a conclusão do download, execute o instalador e siga as instruções. Para o melhor desempenho e compatibilidade, use o back-end WSL 2.

Abra o aplicativo Docker Desktop e aceite o contrato de serviço.

Instale a carga de trabalho do .NET Aspire no Visual Studio

Instale a carga de trabalho do .NET Aspire usando a CLI do .NET:

  1. Abra um terminal.

  2. Atualize as cargas de trabalho do .NET com esse comando:

    dotnet workload update
    

    Você deverá ver uma mensagem informando que as cargas de trabalho foram atualizadas com sucesso.

    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): .
    
  3. Instale a carga de trabalho do .NET Aspire com esse comando:

    dotnet workload install aspire
    

    Você deverá ver uma mensagem informando que a carga de trabalho do Aspire foi instalada.

    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.
    
  4. Verifique se a carga de trabalho do .NET Aspire está instalada com esse comando:

    dotnet workload list
    

    Você deverá ver os detalhes da carga de trabalho 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.
    

Clone e modifique o aplicativo de exemplo

Vamos usar para git obter um aplicativo de amostra criado com o .NET Aspire. O aplicativo ainda não tem cache configurado:

  1. Na linha de comando, navegue até uma pasta de sua escolha onde você possa trabalhar com o código.

  2. Execute o seguinte comando para clonar o aplicativo de amostra Northern Mountains eShop:

    git clone -b aspire-cache https://github.com/MicrosoftDocs/mslearn-aspire-starter
    
  3. Inicie o Visual Studio e selecione Abrir um projeto ou solução.

  4. Navegue até a pasta onde você clonou o eShop, abra a pasta iniciar e selecione o arquivo eShop.rediscache.sln e selecione Abrir.

  5. No Gerenciador de Soluções, navegue até WebApp/Components/Pages e clique duas vezes Catalog.razor.

  6. Localize a seguinte linha de código:

    <SectionContent SectionName="page-header-subtitle">Start the season with the latest in clothing and equipment.</SectionContent>
    
  7. Substitua essa linha pelo seguinte código:

    <SectionContent SectionName="page-header-subtitle">Start the season with the latest in clothing and equipment. It's @DateTime.Now</SectionContent>
    
  8. Para iniciar o aplicativo, pressione F5 ou selecione Depurar>Iniciar Depuração.

  9. Se a caixa de diálogo Iniciar Docker Desktop aparecer, selecione Sim.

  10. Quando o painel eShop .NET Aspire aparecer, para o recurso webapp, selecione um dos ponto de extremidade:

    Captura de tela mostrando onde iniciar o webapp no ​​painel do .NET Aspire.

  11. O ponto de extremidade exibe a página inicial das Montanhas do Norte. Incluindo o tempo no servidor:

    Captura de tela mostrando a página inicial das Montanhas do Norte com o horário do servidor exibido.

  12. Pressione F5 para atualizar a página. Como a página não está armazenada em cache, o tempo exibido muda sempre que você a atualiza, desde que o segundo tenha mudado.

  13. Altere para a guia do navegador que exibe o painel do .NET Aspire e, em seguida, na navegação à esquerda, selecione Traces.

  14. Rastros com o nome webapp: GET / são solicitações para a página inicial. Anote a Duração típica para essas solicitações e, para uma delas, selecione Visualizar na coluna Detalhes:

    Captura de tela com o painel do .NET Aspire mostrando rastreamentos de solicitações para a página inicial da Northern Mountain sem armazenamento em cache.

  15. Na visualização da linha do tempo, observe que o webapp chama vários microsserviços para construir a resposta.

  16. Feche a página inicial das Montanhas do Norte e o painel do .NET Aspire.

  17. No Visual Studio, para interromper a depuração, pressione SHIFT - F5 ou selecione Debug> Stop Debugging.

Adicione um serviço de backup de cache

Agora que você viu o desempenho da página inicial sem armazenamento em cache, vamos adicionar o cache de saída para ver se ele melhora a capacidade de resposta. Comece adicionando o componente de cache de saída ao projeto AppHost:

  1. No Visual Studio, no Gerenciador de Soluções, clique com o botão direito no projeto eShop.AppHost, selecione Adicionar e, em seguida, selecione pacote .NET Aspire.

  2. Na caixa de texto de pesquisa, no final do texto existente, digite Redis.

  3. Selecione o pacote Aspire.Hosting.Redis.

  4. Na lista Versão, selecione a versão 8.0.0 mais recente e selecione Instalar.

  5. Se a caixa de diálogo Visualizar alterações aparecer, selecione Aplicar.

  6. Na caixa de diálogo Aceitação da Licença, selecione Aceito.

  7. No Gerenciador de Soluções, expanda o projeto AppHost e clique duas vezes Program.cs.

  8. Localize as seguintes linhas de código:

    // Databases
    
    var postgres = builder.AddPostgres("postgres").WithPgAdmin();
    var catalogDb = postgres.AddDatabase("CatalogDB");
    
  9. Imediatamente após essas linhas, adicione o seguinte código:

    // Cache
    var redis = builder.AddRedis("cache");
    
  10. Localize a seguinte linha de código, que adiciona o projeto Catalog API à orquestração do .NET Aspire:

    var catalogApi = builder.AddProject<Catalog_API>("catalog-api")
        .WithReference(catalogDb);
    
  11. Para passar o cache Redis para o projeto da API Catalog, substitua esse código pelas seguintes linhas:

    var catalogApi = builder.AddProject<Catalog_API>("catalog-api")
        .WithReference(catalogDb)
        .WithReference(redis);
    

    Observação

    Usaremos o cache na API do Catalog para realizar o cache distribuído.

  12. Localize a seguinte linha de código, que adiciona o projeto WebApp à orquestração do .NET Aspire:

    builder.AddProject<WebApp>("webapp")
        .WithReference(catalogApi);
    
  13. Para passar o cache Redis para o projeto WebApp, substitua esse código pelas seguintes linhas:

    builder.AddProject<WebApp>("webapp")
        .WithReference(catalogApi)
        .WithReference(redis);
    

    Observação

    Usaremos o cache no WebApp para realizar o cache de saída.

  14. Para salvar o arquivo Program.cs, pressione CTRL - S ou selecione Arquivo >Salvar Program.cs.

Use o cache de saída no projeto WebApp

Agora, vamos usar o cache Redis no projeto WebApp para armazenar em cache a saída da página inicial:

  1. No Visual Studio, em Gerenciador de Soluções, clique com o botão direito do mouse no projeto WebApp, selecione Adicionar e, em seguida, selecione pacote .NET Aspire.

  2. Na caixa de texto de pesquisa, no final do texto existente, digite Redis.

  3. Selecione o pacote Aspire.StackExchange.Redis.OutputCaching.

  4. Na lista Versão, selecione a versão 8.0.0 mais recente e selecione Instalar.

  5. Se a caixa de diálogo Visualizar alterações aparecer, selecione Aplicar.

  6. Na caixa de diálogo Aceitação da Licença, selecione Aceito.

  7. Quando a instalação for concluída, em Gerenciador de Soluções, expanda WebApp e clique duas vezes Program.cs.

  8. Localize a seguinte linha de código:

    var builder = WebApplication.CreateBuilder(args);
    
  9. Imediatamente após essa linha, para adicionar o cache de saída ao projeto, adicione esse código:

    builder.AddRedisOutputCache("cache");
    
  10. Localize a seguinte linha de código:

    var app = builder.Build();
    
  11. Imediatamente após essa linha, para adicionar o middleware de cache ao pipeline de solicitação, adicione esse código:

    app.UseOutputCache();
    
  12. Em Gerenciador de Soluções, expanda WebApp > Components > Páginas e clique duas vezes Catalog.razor.

  13. Localize a seguinte linha de código:

    @attribute [StreamRendering]
    
  14. Imediatamente após essa linha, para armazenar em cache a página inicial, adicione esse código:

    @attribute [Microsoft.AspNetCore.OutputCaching.OutputCache(Duration = 10)]
    

Cache de saída de teste

O cache de saída agora está implementado na página inicial das Montanhas do Norte. Vamos testar:

  1. No Visual Studio, para iniciar o aplicativo, pressione F5 ou selecione Debug > Start Debugging.

  2. Quando o painel eShop .NET Aspire aparecer, para o recurso webapp, selecione um dos ponto de extremidade:

    Captura de tela mostrando onde iniciar o webapp no ​​painel do .NET Aspire.

  3. O ponto de extremidade exibe a página inicial das Montanhas do Norte, incluindo o horário no servidor.

  4. Pressione F5 para atualizar a página. Como a página é armazenada em cache por 10 segundos, o tempo exibido muda somente quando passa mais de 10 segundos após a solicitação armazenada em cache.

  5. Altere para a guia do navegador que exibe o painel do .NET Aspire e, em seguida, na navegação à esquerda, selecione Traces.

  6. Rastros com o nome webapp: GET / são solicitações para a página inicial. Algumas solicitações para a página inicial, que não puderam ser atendidas no cache, têm tempos semelhantes às durações que você anotou anteriormente. No entanto, outras solicitações retornadas do cache têm durações significativamente mais curtas.

  7. Para uma das solicitações mais curtas, selecione Visualizar na coluna Detalhes. Observe que a solicitação foi recuperada do cache Redis:

    Captura de tela com o painel do .NET Aspire mostrando um rastreamento de uma solicitação em cache.

  8. Feche a página inicial das Montanhas do Norte e o painel do .NET Aspire.

  9. No Visual Studio, para interromper a depuração, pressione SHIFT - F5 ou selecione Debug> Stop Debugging.

Use cache distribuído

Também podemos usar Redis para realizar cache distribuído no projeto Catalog.API:

  1. No Visual Studio, no Gerenciador de Soluções, clique com o botão direito do mouse no projeto Catalog.API, selecione Adicionar e, em seguida, selecione o pacote .NET Aspire.

  2. Na caixa de texto de pesquisa, no final do texto existente, digite Redis.

  3. Selecione o pacote Aspire.StackExchange.Redis.DistributedCaching.

  4. Na lista Versão, selecione a versão 8.0.0 mais recente e selecione Instalar.

  5. Se a caixa de diálogo Visualizar alterações aparecer, selecione Aplicar.

  6. Na caixa de diálogo Aceitação da Licença, selecione Aceito.

  7. Quando a instalação for concluída, em Gerenciador de Soluções, expanda Catalog.API e clique duas vezes Program.cs.

  8. Localize a seguinte linha de código:

    var builder = WebApplication.CreateBuilder(args);
    
  9. Imediatamente após essa linha, para adicionar o cache de saída ao projeto, adicione esse código:

    builder.AddRedisDistributedCache("cache");
    
  10. No Gerenciador de Soluções expanda Catalog.API > Apis e clique duas vezes CatalogApi.cs.

  11. Localize o seguinte código, que declara o GetAllItems método:

    public static async Task<Results<Ok<PaginatedItems<CatalogItem>>, BadRequest<string>>> GetAllItems(
        [AsParameters] PaginationRequest paginationRequest,
        [AsParameters] CatalogServices services)
    {
    
  12. Para obter o cache Redis por meio de injeção de dependência, modifique esse código para adicionar um novo parâmetro ao método:

    public static async Task<Results<Ok<PaginatedItems<CatalogItem>>, BadRequest<string>>> GetAllItems(
        [AsParameters] PaginationRequest paginationRequest,
        [AsParameters] CatalogServices services,
        IDistributedCache cache)
    {
    
  13. Remova todo o conteúdo do método GetAllItems e substitua-o pelo seguinte código:

    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));
    }
    

Testar cache distribuído

O cache distribuído agora está implementado no projeto Catalog.API. Vamos testar:

  1. No Visual Studio, para iniciar o aplicativo, pressione F5 ou selecione Debug > Start Debugging.

  2. Quando o painel eShop .NET Aspire aparecer, para o recurso catalog-api, selecione o ponto de extremidade:

    Captura de tela mostrando onde iniciar a API do Catálogo no painel do .NET Aspire.

  3. O ponto de extremidade exibe a interface Swagger para o microsserviço da API Catalog. Ao lado do método /api/v1/catalog/items, selecione GET.

  4. Selecione Experimente e selecione Executar. Os resultados são exibidos na janela Corpo da resposta:

    Captura de tela mostrando os resultados do catálogo exibidos na interface do usuário do Swagger.

  5. Clique em Executar mais algumas vezes para chamar a API novamente. Essas solicitações devem obter os itens do cache, desde que a solicitação ocorra menos de 10 segundos após a primeira.

  6. Altere para a guia do navegador que exibe o painel do .NET Aspire e, em seguida, na navegação à esquerda, selecione Traces.

  7. Rastreamentos com o nome catalog-api: GET /api/v1/catalog/items são solicitações para o método items da API do Catálogo. Observe que a primeira solicitação para esse método leva mais tempo para formular as solicitações subsequentes, nas quais a API obtém os itens do cache Redis:

    Captura de tela com a página Traces do painel do .NET Aspire com solicitações em cache para a API do Catálogo.

  8. Feche a página do Swagger e o painel do .NET Aspire.

  9. No Visual Studio, para interromper a depuração, pressione SHIFT - F5 ou selecione Debug> Stop Debugging.