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 atteindre des performances exceptionnelles en exploitant le service Redis hautement évolutif, disponible et sécurisé, sans avoir à gérer de déploiements Redis complexes. Il peut être utilisé comme backend pour la mise en cache des données afin d'améliorer les performances des applications Spring Boot. L'atelier de programmation explique comment le configurer.

Points abordés

  • Comment utiliser Memorystore comme backend de cache pour une application Spring Boot.

Prérequis

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

Comment allez-vous utiliser cet atelier de programmation ?

Je vais le lire uniquement Je vais le lire et effectuer les exercices

Quel est votre niveau d'expérience avec les services Google Cloud ?

Débutant Intermédiaire Expert

Configuration de l'environnement au rythme de chacun

Si vous ne possédez 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 :

Screenshot from 2016-02-10 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 la console Cloud pour pouvoir 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 sans frais avec 300$de crédits.

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.

Une fois connecté à Cloud Shell, vous êtes en principe authentifié, et le projet est déjà défini avec votre 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 serez invité à l'activer. Répondez y (oui).

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 sera prête à être utilisée.

Obtenez l'adresse IP de l'hôte Redis de l'instance en exécutant la commande suivante. Vous l'utiliserez à nouveau 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 à Stockage > Memorystore dans la console Google Cloud, vous devriez pouvoir voir votre instance à l'état "Prêt" :

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 sera prête à être utilisée.

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

Dans le shell de l'instance de machine virtuelle (VM), et non dans Cloud Shell, installez OpenJDK, Maven et telnet :

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

Attendez la fin de l'installation, 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 avec votre adresse IP Memorystore pour Redis (obtenue il y a quelques étapes) :

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

Ajoutez une nouvelle ligne et créez une classe Java de contrôleur REST :

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

Insérez le contenu suivant dans le 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". Elle est utilisée en combinaison avec la valeur du paramètre comme clé de cache. Vous verrez un exemple plus loin dans l'atelier de programmation.

Vous devez également activer la mise en cache dans la classe d'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. Voici le résultat attendu :

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 maintenant prêt à exécuter l'application.

$ mvn spring-boot:run

Ouvrez une autre connexion SSH à votre instance de la même manière que précédemment. Dans la nouvelle fenêtre SSH, accédez plusieurs fois au point de terminaison /hello/ 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, malgré le fait que vous ayez Thread.sleep(5000)invocation dans la méthode. En effet, la méthode réelle n'a été exécutée qu'une seule fois et le résultat a été placé dans le cache. Chaque appel suivant renvoie le résultat directement à partir du cache.

Vous pouvez voir exactement ce que l'application a mis en cache. À partir du même terminal que celui utilisé à l'étape précédente, 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 le nettoyage, supprimez les instances Compute Engine et Memorystore depuis 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éé une instance 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.