Mettre en cache les données d'une application Spring Boot avec Memorystore

Memorystore pour Redis est un service Redis entièrement géré pour Google Cloud. Les applications exécutées sur Google Cloud peuvent bénéficier de performances extrêmes en exploitant le service Redis hautement évolutif, disponible et sécurisé, sans avoir à gérer de déploiements Redis complexes. Il peut être utilisé en tant que backend pour la mise en cache des données afin d'améliorer les performances des applications Spring Boot. Cet atelier de programmation vous explique comment le configurer.

Points abordés

  • Utiliser Memorystore comme backend de cache pour une application Spring Boot

Prérequis

  • Un projet Google Cloud
  • Un navigateur tel que Google Chrome
  • Une bonne connaissance des éditeurs de texte Linux standards tels que Vim, Emacs et GNU Nano

Comment allez-vous utiliser l'atelier de programmation ?

Lecture seule Lire et terminer les exercices

Comment évalueriez-vous votre expérience avec les services Google Cloud ?

Débutant Intermédiaire Compétent

Configuration de l'environnement au rythme de chacun

Si vous n'avez pas encore de compte Google (Gmail ou Google Apps), vous devez en créer un. Connectez-vous à la console Google Cloud Platform (console.cloud.google.com) et créez un projet:

Capture d'écran du 10/02/2016 12:45:26.png

Mémorisez l'ID du projet. Il s'agit d'un nom unique permettant de différencier chaque projet Google Cloud (le nom ci-dessus est déjà pris ; vous devez en trouver un autre). Il sera désigné par le nom PROJECT_ID tout au long de cet atelier de programmation.

Vous devez ensuite activer la facturation dans Cloud Console afin d'utiliser les ressources Google Cloud.

Suivre cet atelier de programmation ne devrait pas vous coûter plus d'un euro. Cependant, cela peut s'avérer plus coûteux si vous décidez d'utiliser davantage de ressources ou si vous n'interrompez pas les ressources (voir la section "Effectuer un nettoyage" à la fin du présent document).

Les nouveaux utilisateurs de Google Cloud Platform peuvent bénéficier d'un essai offert de 300$.

Activer Google Cloud Shell

Depuis la console GCP, cliquez sur l'icône Cloud Shell de la barre d'outils située dans l'angle supérieur droit :

Cliquez ensuite sur "Démarrer Cloud Shell" :

Le provisionnement de l'environnement et la connexion ne devraient pas prendre plus de quelques minutes :

Cette machine virtuelle contient tous les outils de développement nécessaires. Elle intègre un répertoire d'accueil persistant de 5 Go et s'exécute sur Google Cloud, ce qui améliore nettement les performances du réseau et l'authentification. Vous pouvez réaliser une grande partie, voire la totalité, des activités de cet atelier dans un simple navigateur ou sur votre Chromebook Google.

En principe, une fois que vous êtes connecté à Cloud Shell, vous êtes authentifié, et le projet est défini sur PROJECT_ID.

Exécutez la commande suivante dans Cloud Shell pour vérifier que vous êtes authentifié :

gcloud auth list

Résultat de la commande

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

Résultat de la commande

[core]
project = <PROJECT_ID>

Si vous obtenez un résultat différent, exécutez cette commande :

gcloud config set project <PROJECT_ID>

Résultat de la commande

Updated property [core/project].

Démarrez Cloud Shell.

Après le lancement de Cloud Shell, vous pouvez utiliser la ligne de commande pour créer une instance Memorystore.

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

Si l'API Memorystore n'est pas activée, vous êtes invité à l'activer. Répondez 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].

Une fois l'opération terminée, votre instance est prête à être utilisée.

Pour obtenir l'adresse IP de l'hôte Redis de l'instance, exécutez la commande suivante. Vous l'utiliserez plus tard pour configurer votre application Spring Boot.

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

Si vous accédez à Storage > Memorystore dans Google Cloud Console, vous devriez pouvoir voir votre instance dans "ready" state :

Créez une instance Compute Engine dans la même région.

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

Une fois l'opération terminée, votre instance est prête à être utilisée.

Connectez-vous à votre instance via SSH en accédant à Compute > Compute Engine > VM instances (Instances de VM), puis cliquez sur SSH dans la colonne Connect (Connexion) :

Dans l'interface système de l'instance de machine virtuelle (VM), et non Cloud Shell, installez OpenJDK, Maven, telnet:

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

Attendez que l'installation se termine, puis passez à l'étape suivante.

Créez un projet Spring Boot avec les dépendances web, redis et 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

Modifiez le fichier application.properties pour configurer l'application afin qu'elle utilise l'adresse IP de l'instance Memorystore pour l'hôte Redis.

$ nano src/main/resources/application.properties

Ajoutez la ligne suivante à votre adresse IP Memorystore pour Redis (à partir de quelques étapes):

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

Ajoutez ensuite une ligne, puis créez une classe Java pour le contrôleur REST:

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

Ajoutez le contenu suivant au fichier:

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

L'annotation @RequestMapping expose la méthode en tant que point de terminaison HTTP et mappe une partie du chemin d'accès à un paramètre de méthode (comme indiqué par l'annotation @PathVariable).

L'annotation @Cacheable("hello") indique que l'exécution de la méthode doit être mise en cache et que le nom du cache est "hello." Il est utilisé conjointement avec la valeur du paramètre en tant que clé de cache. Vous verrez un exemple dans la suite de l'atelier de programmation.

Vous devez également activer la mise en cache dans la classe de l'application Spring Boot.

Modifier DemoApplication.java:

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

Importez org.springframework.cache.annotation.EnableCaching et annotez la classe avec cette annotation. Le résultat doit ressembler à ceci :

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

Vous êtes prêt à exécuter l'application !

$ mvn spring-boot:run

Ouvrez une autre connexion SSH sur votre instance comme vous l'avez fait précédemment. Dans la nouvelle fenêtre SSH, accédez au point de terminaison /hello/ à plusieurs reprises en transmettant "bob" comme nom.

$ 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

Notez que la première requête a pris cinq secondes, mais que la suivante a été beaucoup plus rapide, bien que la méthode Thread.sleep(5000)ait été appelée. Cela s'explique par le fait que la méthode réelle n'a été exécutée qu'une seule fois et que le résultat a été placé dans le cache. Chaque appel ultérieur renvoie le résultat directement depuis le cache.

Vous pouvez voir exactement ce que l'application a mis en cache. Depuis le terminal que vous avez utilisé précédemment, connectez-vous à l'hôte Memorystore pour Redis à l'aide de telnet:

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

Pour afficher la liste des clés de cache, utilisez la commande suivante:

KEYS *
hello::bob

Comme vous pouvez le constater, le nom du cache est utilisé comme préfixe pour la clé et la valeur du paramètre est utilisée comme deuxième partie.

Pour récupérer la valeur, utilisez la commande GET:

$ GET hello::bob
   Hello bob!

Utilisez la commande QUIT pour quitter.

Pour effectuer un nettoyage, supprimez les instances Compute Engine et Memorystore de Cloud Shell.

Supprimez l'instance de calcul:

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

Supprimez l'instance Memorystore pour Redis:

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

Vous avez créé Memorystore pour Redis et une instance Compute Engine. Vous avez également configuré une application Spring Boot pour utiliser Memorystore avec la mise en cache Spring Boot.

En savoir plus

Licence

Ce document est publié sous une licence Creative Commons Attribution 2.0 Generic.