Se connecter à une instance Redis depuis Cloud Functions

Vous pouvez vous connecter à une instance Redis à partir de Cloud Functions à l'aide de l'accès au VPC sans serveur.

Prérequis

Si vous avez déjà installé le SDK Cloud et créé une instance Redis, vous pouvez ignorer ces étapes.

  1. Installez le SDK Cloud et initialisez :

    gcloud init
    
  2. Suivez le Guide de démarrage rapide pour créer une instance Redis. Retenez la zone, l'adresse IP et le port de l'instance Redis.

Configurer l'accès au VPC sans serveur

Pour vous connecter à partir de Cloud Functions au réseau VPC autorisé de votre instance Redis, vous devez configurer l'accès au VPC sans serveur.

  1. Recherchez le réseau autorisé de votre instance Redis en exécutant la commande suivante :

    gcloud beta redis instances describe [INSTANCE_ID] --region [REGION]
    
  2. Suivez les instructions de la section Créer un connecteur pour créer un connecteur d'accès au VPC sans serveur. Veillez à créer le connecteur dans la même région que votre fonction et assurez-vous qu'il est associé au réseau VPC autorisé de l'instance Redis. Mémorisez le nom du connecteur.

Exemple de fonction

Cet exemple de fonction établit une connexion à une instance Redis à partir de Cloud Functions.

Clonez le dépôt correspondant au langage de programmation souhaité et accédez au dossier contenant l'exemple de code :

Go

git clone https://github.com/GoogleCloudPlatform/golang-samples
cd golang-samples/functions/memorystore/redis

Node.js

git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples
cd nodejs-docs-samples/functions/memorystore/redis

Python

git clone https://github.com/GoogleCloudPlatform/python-docs-samples
cd python-docs-samples/functions/memorystore/redis

L'exemple de code incrémente un compteur Redis chaque fois que la fonction est déclenchée.

Go

Cette fonction utilise le client github.com/gomodule/redigo/redis.


// Package visitcount provides a Cloud Function that connects
// to a managed Redis instance.
package visitcount

import (
	"errors"
	"fmt"
	"log"
	"net/http"
	"os"

	"github.com/gomodule/redigo/redis"
)

var redisPool *redis.Pool

// initializeRedis initializes and returns a connection pool
func initializeRedis() (*redis.Pool, error) {
	redisHost := os.Getenv("REDISHOST")
	if redisHost == "" {
		return nil, errors.New("REDISHOST must be set")
	}
	redisPort := os.Getenv("REDISPORT")
	if redisPort == "" {
		return nil, errors.New("REDISPORT must be set")
	}
	redisAddr := fmt.Sprintf("%s:%s", redisHost, redisPort)

	const maxConnections = 10
	return &redis.Pool{
		MaxIdle: maxConnections,
		Dial: func() (redis.Conn, error) {
			c, err := redis.Dial("tcp", redisAddr)
			if err != nil {
				return nil, fmt.Errorf("redis.Dial: %v", err)
			}
			return c, err
		},
	}, nil
}

// VisitCount increments the visit count on the Redis instance
// and prints the current count in the HTTP response.
func VisitCount(w http.ResponseWriter, r *http.Request) {
	// Initialize connection pool on first invocation
	if redisPool == nil {
		// Pre-declare err to avoid shadowing redisPool
		var err error
		redisPool, err = initializeRedis()
		if err != nil {
			log.Printf("initializeRedis: %v", err)
			http.Error(w, "Error initializing connection pool", http.StatusInternalServerError)
			return
		}
	}

	conn := redisPool.Get()
	defer conn.Close()

	counter, err := redis.Int(conn.Do("INCR", "visits"))
	if err != nil {
		log.Printf("redis.Int: %v", err)
		http.Error(w, "Error incrementing visit count", http.StatusInternalServerError)
		return
	}
	fmt.Fprintf(w, "Visit count: %d", counter)
}

Node.js

Cette fonction utilise le module redis.


const {promisify} = require('util');
const redis = require('redis');

const REDISHOST = process.env.REDISHOST || 'localhost';
const REDISPORT = process.env.REDISPORT || 6379;

const redisClient = redis.createClient(REDISPORT, REDISHOST);
redisClient.on('error', err => console.error('ERR:REDIS:', err));

const incrAsync = promisify(redisClient.incr).bind(redisClient);

exports.visitCount = async (req, res) => {
  try {
    const response = await incrAsync('visits');
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end(`Visit count: ${response}`);
  } catch (err) {
    console.log(err);
    res.status(500).send(err.message);
  }
};

Python

Cette fonction utilise le package redis-py.


import os

import redis

redis_host = os.environ.get('REDISHOST', 'localhost')
redis_port = int(os.environ.get('REDISPORT', 6379))
redis_client = redis.StrictRedis(host=redis_host, port=redis_port)

def visit_count(request):
    value = redis_client.incr('visits', 1)
    return 'Visit count: {}'.format(value)

Déployer l'exemple sur Cloud Functions

Déployez la fonction à l'aide de l'outil de ligne de commande gcloud :

Go

gcloud functions deploy VisitCount \
--runtime go111 \
--trigger-http \
--region [REGION] \
--vpc-connector projects/[PROJECT_ID]/locations/[REGION]/connectors/[CONNECTOR_NAME] \
--set-env-vars REDISHOST=[REDIS_IP],REDISPORT=[REDIS_PORT]

Node.js

gcloud functions deploy visitCount \
--runtime nodejs10 \
--trigger-http \
--region [REGION] \
--vpc-connector projects/[PROJECT_ID]/locations/[REGION]/connectors/[CONNECTOR_NAME] \
--set-env-vars REDISHOST=[REDIS_IP],REDISPORT=[REDIS_PORT]

Python

gcloud functions deploy visit_count \
--runtime python37 \
--trigger-http \
--region [REGION] \
--vpc-connector projects/[PROJECT_ID]/locations/[REGION]/connectors/[CONNECTOR_NAME] \
--set-env-vars REDISHOST=[REDIS_IP],REDISPORT=[REDIS_PORT]

où :

  • [PROJECT_ID] est l'ID de votre projet Google Cloud.
  • [REGION] est la région dans laquelle vous souhaitez déployer l'application.
  • [CONNECTOR_NAME] est le nom du connecteur.
  • [REDIS_IP] et [REDIS_PORT] sont l'adresse IP et le numéro de port de votre instance Redis.

Une fois le déploiement de la fonction terminé, augmentez le nombre de visites en envoyant une requête GET à l'URL de votre fonction :

Go

https://[REGION]-[PROJECT_ID].cloudfunctions.net/VisitCount

Node.js

https://[REGION]-[PROJECT_ID].cloudfunctions.net/visitCount

Python

https://[REGION]-[PROJECT_ID].cloudfunctions.net/visit_count