Armazenar dados em cache de um aplicativo Spring Boot com o Memorystore

1. Visão geral

O Memorystore para Redis é um serviço Redis totalmente gerenciado para o Google Cloud. Os apps em execução no Google Cloud podem alcançar desempenho máximo aproveitando o serviço Redis altamente escalonável, disponível e seguro sem o trabalho de gerenciar implantações complexas do Redis. Ele pode ser usado como um back-end para o armazenamento em cache de dados e melhorar o desempenho dos apps Spring Boot. O codelab explica como configurar.

O que você vai aprender

  • Como usar o Memorystore como um back-end de cache para um app do Spring Boot.

O que é necessário

  • um projeto do Google Cloud;
  • Um navegador, como o Google Chrome
  • Conhecer os editores de texto padrão do Linux, como Vim, Emacs e GNU Nano

Como você vai usar o codelab?

Somente leitura Ler e fazer os exercícios

Como você classificaria sua experiência com os serviços do Google Cloud?

Iniciante Intermediário Proficiente

2. Configuração e requisitos

Configuração de ambiente autoguiada

  1. Faça login no Console do Cloud e crie um novo projeto ou reutilize um existente. Crie uma se você ainda não tiver uma conta do Gmail ou do G Suite.

dMbN6g9RawQj_VXCSYpdYncY-DbaRzr2GbnwoV7jFf1u3avxJtmGPmKpMYgiaMH-qu80a_NJ9p2IIXFppYk8x3wyymZXavjglNLJJhuXieCem56H30hwXtd8PvXGpXJO9gEUDu3cZw

ci9Oe6PgnbNuSYlMyvbXF1JdQyiHoEgnhl4PlV_MFagm2ppzhueRkqX4eLjJllZco_2zCp0V0bpTupUSKji9KkQyWqj11pqit1K1faS1V6aFxLGQdkuzGp4rsQTan7F01iePL5DtqQ

8-tA_Lheyo8SscAVKrGii2coplQp2_D1Iosb2ViABY0UUO1A8cimXUu6Wf1R9zJIRExL5OB2j946aIiFtyKTzxDcNnuznmR45vZ2HMoK3o67jxuoUJCAnqvEX6NgPGFjCVNgASc-lg

Lembre-se do código do projeto, um nome exclusivo em todos os projetos do Google Cloud. O nome acima já foi escolhido e não servirá para você. Faremos referência a ele mais adiante neste codelab como PROJECT_ID.

  1. Em seguida, será necessário ativar o faturamento no Console do Cloud para usar os recursos do Google Cloud.

A execução deste codelab não será muito cara, se for o caso. Siga todas as instruções na seção "Limpeza", que orienta você sobre como encerrar recursos para não incorrer em cobranças além deste tutorial. Novos usuários do Google Cloud estão qualificados para o programa de US$ 300 de avaliação sem custos.

Ativar o Cloud Shell

  1. No Console do Cloud, clique em Ativar o Cloud ShellH7JlbhKGHITmsxhQIcLwoe5HXZMhDlYue4K-SPszMxUxDjIeWfOHBfxDHYpmLQTzUmQ7Xx8o6OJUlANnQF0iBuUyfp1RzVad_4nCa0Zz5LtwBlUZFXFCWFrmrWZLqg1MkZz2LdgUDQ.

zlNW0HehB_AFW1qZ4AyebSQUdWm95n7TbnOr7UVm3j9dFcg6oWApJRlC0jnU1Mvb-IQp-trP1Px8xKNwt6o3pP6fyih947sEhOFI4IRF0W7WZk6hFqZDUGXQQXrw21GuMm2ecHrbzQ

Se você nunca tiver iniciado o Cloud Shell, verá uma tela intermediária (abaixo da dobra) com a descrição do que ele é. Se esse for o caso, clique em Continuar e você não o verá novamente. Esta é uma tela única:

kEPbNAo_w5C_pi9QvhFwWwky1cX8hr_xEMGWySNIoMCdi-Djx9AQRqWn-__DmEpC7vKgUtl-feTcv-wBxJ8NwzzAp7mY65-fi2LJo4twUoewT1SUjd6Y3h81RG3rKIkqhoVlFR-G7w

Leva apenas alguns instantes para provisionar e se conectar ao Cloud Shell.

pTv5mEKzWMWp5VBrg2eGcuRPv9dLInPToS-mohlrqDASyYGWnZ_SwE-MzOWHe76ZdCSmw0kgWogSJv27lrQE8pvA5OD6P1I47nz8vrAdK7yR1NseZKJvcxAZrPb8wRxoqyTpD-gbhA

Essa máquina virtual contém todas as ferramentas de desenvolvimento necessárias. Ela oferece um diretório principal persistente de 5 GB, além de ser executada no Google Cloud. Isso aprimora o desempenho e a autenticação da rede. Praticamente todo o seu trabalho neste codelab pode ser feito em um navegador ou no seu Chromebook.

Depois de se conectar ao Cloud Shell, você já estará autenticado e o projeto já estará configurado com seu ID do projeto.

  1. Execute o seguinte comando no Cloud Shell para confirmar que você está autenticado:
gcloud auth list

Resposta ao comando

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
gcloud config list project

Resposta ao comando

[core]
project = <PROJECT_ID>

Se o projeto não estiver configurado, configure-o usando este comando:

gcloud config set project <PROJECT_ID>

Resposta ao comando

Updated property [core/project].

3. Configurar uma instância do Memorystore para Redis

Inicie o Cloud Shell.

Depois que o Cloud Shell for iniciado, use a linha de comando para ativar a API Memorystore e criar uma instância do Memorystore.

$ gcloud services enable redis.googleapis.com
$ gcloud redis instances create myinstance --size=1 --region=us-central1

Depois que a operação for concluída, sua instância estará pronta para uso.

Execute o comando a seguir para receber o endereço IP do host do Redis da instância. Você vai usá-lo novamente mais tarde ao configurar o app Spring Boot.

$ gcloud redis instances describe myinstance --region=us-central1 \
  | grep host
host: 10.0.0.4

No console do Google Cloud, acesse Bancos de dados > Memorystore > Redis. A instância precisa estar no estado "pronta":

ee90b43f15a6dc1f.png

4. Configurar uma instância do Compute Engine

Crie uma instância do Compute Engine na mesma região.

$ gcloud compute instances create instance-1 --zone us-central1-c

Depois que a operação for concluída, sua instância estará pronta para uso.

Conecte-se à instância via SSH com o seguinte comando:

$ gcloud compute ssh instance-1 --zone us-central1-c

Outra opção é acessar Compute > Compute Engine > Instâncias de VM e clicar em SSH na coluna Conectar:

a87bd437a0c8c7b4.png

No shell da instância de máquina virtual (VM), não no Cloud Shell, instale o OpenJDK, o Maven e as ferramentas do Redis:

$ sudo apt-get install openjdk-17-jdk-headless maven redis-tools

Aguarde a conclusão da instalação e siga para a próxima etapa.

5. Configurar um app Spring Boot

Crie um projeto Spring Boot com as dependências web, redis e cache:

$ curl https://start.spring.io/starter.tgz \
  -d dependencies=web,redis,cache -d language=java -d baseDir=cache-app \
  -d type=maven-project \
  | tar -xzvf - && cd cache-app

Edite o arquivo application.properties para configurar o app de modo que ele use o endereço IP da instância do Memorystore para host do Redis.

$ nano src/main/resources/application.properties

Adicione a seguinte linha com seu endereço IP do Memorystore para Redis (de algumas etapas atrás):

spring.data.redis.host=<memorystore-host-ip-address> 

Adicione uma nova linha depois disso e crie uma classe Java de controlador REST:

$ nano src/main/java/com/example/demo/HelloWorldController.java

Coloque o seguinte conteúdo no arquivo:

package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloWorldController {
@Autowired
private StringRedisTemplate template;

@RequestMapping("/hello/{name}")
@Cacheable("hello")
public String hello(@PathVariable String name) throws InterruptedException {
  Thread.sleep(5000);
  return "Hello " + name;
 }
}

A anotação @RequestMapping expõe o método como um endpoint HTTP e mapeia parte do caminho para um parâmetro de método (conforme indicado pela anotação @PathVariable).

A anotação @Cacheable("hello") indica que a execução do método precisa ser armazenada em cache, e o nome do cache é "hello". Ela é usada em combinação com o valor de parâmetro como uma chave de cache. Você vai ver um exemplo mais adiante neste codelab.

Em seguida, vamos ativar o armazenamento em cache na classe do app Spring Boot. Editar DemoApplication.java:

$ nano src/main/java/com/example/demo/DemoApplication.java

Importe org.springframework.cache.annotation.EnableCaching e adicione essa anotação à classe. O resultado ficará assim:

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication
@EnableCaching
public class DemoApplication {

public static void main(String[] args) {
  SpringApplication.run(DemoApplication.class, args);
 }
}

6. Executar o app e acessar o endpoint

Verifique se JAVA_HOME está definido com a versão correta:

export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64/

Agora você já pode executar o app.

$ mvn spring-boot:run

Abra outra conexão SSH com a instância da mesma forma que fez antes. Na nova janela SSH, acesse o endpoint /hello/ várias vezes, transmitindo "bob" como nome.

$ time curl http://localhost:8080/hello/bob
Hello bob!

real        0m5.408s
user        0m0.036s
sys        0m0.009s

$ time curl http://localhost:8080/hello/bob
Hello bob!

real        0m0.092s
user        0m0.021s
sys        0m0.027s

A primeira vez que a solicitação levou cinco segundos, mas a próxima foi significativamente mais rápida, apesar de você ter Thread.sleep(5000)invocação no método. Isso acontece porque o método real foi executado apenas uma vez e o resultado foi colocado no cache. Cada chamada subsequente retorna o resultado diretamente do cache.

7. Analisar objetos armazenados em cache

Você pode ver exatamente o que o app armazenou em cache. No mesmo terminal usado na etapa anterior, conecte-se ao host do Memorystore para Redis usando o redis-cli:

$ redis-cli -h <memorystore-host-ip-address>

Para conferir a lista de chaves de cache, use o seguinte comando:

:6379> KEYS *
1) "hello::bob"

Como você pode ver, o nome do cache é usado como prefixo para a chave, e o valor de parâmetro é usado como a segunda parte.

Para recuperar o valor, use o comando GET:

:6379> GET hello::bob
   Hello bob!

Use o comando exit para sair.

8. Limpar

Para limpar, exclua as instâncias do Compute Engine e do Memorystore do Cloud Shell.

Exclua a instância de computação:

$ gcloud compute instances delete instance-1 --zone us-central1-c

Exclua a instância do Memorystore para Redis:

$ gcloud redis instances delete myinstance --region=us-central1

9. Parabéns!

Você criou o Memorystore para Redis e uma instância do Compute Engine. Além disso, você configurou um app do Spring Boot para usar o Memorystore com o armazenamento em cache do Spring Boot.

Saiba mais

Licença

Este conteúdo está sob a licença Atribuição 2.0 Genérica da Creative Commons.