Armazenar em cache os dados de um app do Spring Boot com o Memorystore

Armazenar em cache os dados de um app do Spring Boot com o Memorystore

Sobre este codelab

subjectÚltimo fev. 11, 2020 atualizado
account_circleEscrito por um Googler

1. Visão geral

O Memorystore para Redis é um serviço Redis totalmente gerenciado para o Google Cloud. Os aplicativos em execução no Google Cloud podem ter um desempenho extremo utilizando o serviço Redis altamente escalonável, disponível e seguro, sem a necessidade de gerenciar implantações complexas do Redis. Ele pode ser usado como back-end para armazenamento em cache de dados a fim de melhorar o desempenho dos apps do Spring Boot. O codelab explica como configurá-lo.

O que você aprenderá

  • Como usar o Memorystore como back-end de cache em um app de inicialização do Spring.

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ê usará o codelab?

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

2. Configuração e requisitos

Configuração de ambiente personalizada

Se você ainda não tem uma Conta do Google (Gmail ou Google Apps), crie uma. Faça login no Console do Google Cloud Platform (console.cloud.google.com) e crie um novo projeto:

Captura de tela de 10/02/2016 12:45:26.png

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.

Em seguida, você precisará ativar o faturamento no Console do Cloud para usar os recursos do Google Cloud.

A execução por meio deste codelab terá um custo baixo, mas poderá ser mais se você decidir usar mais recursos ou se deixá-los em execução. Consulte a seção "limpeza" no final deste documento.

Novos usuários do Google Cloud Platform estão qualificados para um teste sem custo financeiro de US$300.

Ativa o Google Cloud Shell

No Console do GCP, clique no ícone do Cloud Shell na barra de ferramentas localizada no canto superior direito:

Em seguida, clique em "Start Cloud Shell":

O provisionamento e a conexão ao ambiente levarão apenas alguns instantes para serem concluídos:

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 laboratório pode ser feito em um navegador ou no seu Google Chromebook.

Depois que você se conectar ao Cloud Shell, sua autenticação já terá sido feita, e o projeto estará definido com seu PROJECT_ID.

Execute o seguinte comando no Cloud Shell para confirmar se a conta está autenticada:

gcloud auth list

Resposta ao comando

Credentialed accounts:
 - <myaccount>@<mydomain>.com (active)
gcloud config list project

Resposta ao comando

[core]
project = <PROJECT_ID>

Se o projeto não estiver configurado, faça a configuraçã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, será possível usar a linha de comando para criar uma nova instância do Memorystore.

$ gcloud redis instances create myinstance --size=1 --region=us-central1

Se a API Memorystore não estiver ativada, será perguntado se você quer ativá-la. Responda y.

API [redis.googleapis.com] not enabled on project [204466653457].
Would you like to enable and retry (this will take a few minutes)?
(y/N)?  y
Enabling service redis.googleapis.com on project 204166153457...
Waiting for async operation operations/tmo-acf.c8909997-1b4e-1a62-b6f5-7da75cce1416 to complete...
Operation finished successfully. The following command can describe the Operation details:
 gcloud services operations describe operations/tmo-acf.c8909997-1b4e-1a62-b6f5-7da75cce1416
Create request issued for: [myinstance]
Waiting for operation [operation-1538645026454-57763b937ad39-2564ab37-3fea7701] to complete...done.
Created instance [myinstance].

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

Para descobrir o endereço IP da instância do Redis da instância, execute o comando abaixo. Você precisará 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

Ao acessar Storage > Memorystore no Console do Google Cloud, você verá a instância no estado "ready":

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

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

Conecte-se à sua instância via SSH acessando Compute > Compute Engine > Instâncias de VM e clique em SSH na coluna Conectar:

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

$ sudo apt-get install openjdk-8-jdk-headless maven telnet

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

5. Configurar um app Spring Boot

Crie um novo projeto Spring Boot com 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 \
  | tar -xzvf - && cd cache-app

Edite o arquivo application.properties para configurar o app para usar o endereço IP da instância do Memorystore para host do Redis.

$ nano src/main/resources/application.properties

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

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

Adicione uma nova linha depois disso e crie uma classe Java do 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 deve ser armazenada em cache e que o nome do cache é "hello." É usado em combinação com o valor do parâmetro como uma chave de cache. Você verá um exemplo mais adiante no codelab.

Além disso, é necessário 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 faça uma anotação na classe com essa anotação. 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

Agora está tudo pronto para você executar o app.

$ mvn spring-boot:run

Abra outra conexão SSH com a instância, como 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 ocorre porque o método real é executado apenas uma vez e o resultado é colocado no cache. Cada chamada subsequente retorna o resultado diretamente do cache.

7. Revisar objetos armazenados em cache

Você pode ver exatamente o que o app armazena em cache. No mesmo terminal que você usou na etapa anterior, conecte-se ao host do Memorystore para Redis usando telnet:

$ telnet <memorystore-host-ip-address> 6379

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

KEYS *
hello::bob

Como podemos ver, o nome do cache é usado como prefixo da chave, e o valor do parâmetro é usado como a segunda parte.

Para recuperar o valor, use o comando GET:

$ GET hello::bob
   Hello bob!

Use o comando QUIT para sair.

8. Limpar

Para fazer a limpeza, exclua as instâncias do Compute Engine e Memorystore do Cloud Shell.

Exclua a instância do Compute:

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

Exclua a instância do Memorystore for 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 aplicativo Spring Boot para usar o Memorystore com o cache de inicialização do Spring.

Saiba mais

Licença

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