Conéctate a una instancia de Redis desde un servicio de Cloud Run

Puedes conectarte a una instancia de Redis desde Cloud Run mediante el Acceso a VPC sin servidores.

Configuración

Si ya instalaste el SDK de Cloud y creaste una instancia de Redis, puedes omitir estos pasos.

  1. Instala el SDK de Cloud y, luego, inicializa:

    gcloud init
    
  2. Sigue la Guía de inicio rápido para crear una instancia de Redis. Anota la zona, la dirección IP y el puerto de la instancia de Redis.

Configura el Acceso a VPC sin servidores

Para conectarte a tu instancia de Redis, tu servicio de Cloud Run necesita acceder a la red de VPC autorizada de la instancia de Redis. Para habilitar este acceso, necesitas un conector de Acceso a VPC sin servidores:

  1. Busca el nombre de la red autorizada de tu instancia de Redis con el siguiente comando:

    gcloud redis instances describe INSTANCE_ID --region REGION --format "value(authorizedNetwork)"
    
  2. Sigue las instrucciones para crear un conector a fin de crear un conector de Acceso a VPC sin servidores. Asegúrate de crear el conector en la misma región que tu aplicación de Cloud Run y de conectar la conexión a la red de VPC autorizada de la instancia de Redis. Recuerda el nombre del conector.

Aplicación de muestra

Esta aplicación de servidor HTTP de muestra establece una conexión con una instancia de Redis desde un servicio de Cloud Run.

Clona el repositorio de tu lenguaje de programación deseado y navega a la carpeta que contiene el código de muestra:

Go

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

Node.js

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

Python

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

Esta aplicación de muestra aumenta un contador de Redis cada vez que se accede al extremo /.

Go

En esta aplicación, se usa el cliente github.com/gomodule/redigo/redis. Para instalarla, ejecuta el siguiente comando:

go get github.com/gomodule/redigo/redis

// Command redis is a basic app that connects to a managed Redis instance.
package main

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

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

var redisPool *redis.Pool

func incrementHandler(w http.ResponseWriter, r *http.Request) {
	conn := redisPool.Get()
	defer conn.Close()

	counter, err := redis.Int(conn.Do("INCR", "visits"))
	if err != nil {
		http.Error(w, "Error incrementing visitor counter", http.StatusInternalServerError)
		return
	}
	fmt.Fprintf(w, "Visitor number: %d", counter)
}

func main() {
	redisHost := os.Getenv("REDISHOST")
	redisPort := os.Getenv("REDISPORT")
	redisAddr := fmt.Sprintf("%s:%s", redisHost, redisPort)

	const maxConnections = 10
	redisPool = &redis.Pool{
		MaxIdle: maxConnections,
		Dial:    func() (redis.Conn, error) { return redis.Dial("tcp", redisAddr) },
	}

	http.HandleFunc("/", incrementHandler)

	port := os.Getenv("PORT")
	if port == "" {
		port = "8080"
	}
	log.Printf("Listening on port %s", port)
	if err := http.ListenAndServe(":"+port, nil); err != nil {
		log.Fatal(err)
	}
}

Node.js

En esta aplicación, se usa el módulo redis.

{
  "name": "memorystore-redis",
  "description": "An example of using Memorystore(Redis) with Node.js",
  "version": "0.0.1",
  "private": true,
  "license": "Apache Version 2.0",
  "author": "Google Inc.",
  "engines": {
    "node": ">=8.0.0"
  },
  "dependencies": {
    "redis": "^3.0.0"
  }
}

'use strict';
const http = require('http');
const redis = require('redis');

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

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

// create a server
http
  .createServer((req, res) => {
    // increment the visit counter
    client.incr('visits', (err, reply) => {
      if (err) {
        console.log(err);
        res.status(500).send(err.message);
        return;
      }
      res.writeHead(200, {'Content-Type': 'text/plain'});
      res.end(`Visitor number: ${reply}\n`);
    });
  })
  .listen(8080);

Python

Esta aplicación usa Flask para la entrega web y el paquete redis-py a fin de comunicarse con la instancia de Redis.

Flask==2.0.1
gunicorn==20.1.0
redis==3.5.3
import logging
import os

from flask import Flask
import redis

app = Flask(__name__)

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)

@app.route('/')
def index():
    value = redis_client.incr('counter', 1)
    return 'Visitor number: {}'.format(value)

@app.errorhandler(500)
def server_error(e):
    logging.exception('An error occurred during a request.')
    return """
    An internal error occurred: <pre>{}</pre>
    See logs for full stacktrace.
    """.format(e), 500

if __name__ == '__main__':
    # This is used when running locally. Gunicorn is used to run the
    # application on Google App Engine and Cloud Run.
    # See entrypoint in app.yaml or Dockerfile.
    app.run(host='127.0.0.1', port=8080, debug=True)

Implementa la aplicación en Cloud Run

Para implementar la aplicación, haz lo siguiente:

  1. Copia el archivo Dockerfile en el directorio fuente:

    cp cloud_run_deployment/Dockerfile .
    
  2. Compila una imagen de contenedor mediante Cloud Build con el siguiente comando:

    gcloud builds submit --tag gcr.io/PROJECT_ID/visit-count
    
  3. Implementa el contenedor en Cloud Run:

    gcloud run deploy \
    --image gcr.io/PROJECT_ID/visit-count \
    --platform managed \
    --allow-unauthenticated \
    --region REGION \
    --vpc-connector CONNECTOR_NAME \
    --set-env-vars REDISHOST=REDIS_IP,REDISPORT=REDIS_PORT
    

    Donde:

    • PROJECT_ID es el ID de tu proyecto de Google Cloud.
    • REGION es la misma región en la que se encuentran el conector de acceso a VPC sin servidores y la instancia de Redis.
    • CONNECTOR_NAME es el nombre del conector.
    • REDIS_IP y REDIS_PORT son la dirección IP y el número de puerto de la instancia de Redis.

Una vez que la implementación se complete de forma correcta, la línea de comandos mostrará la URL de tu servicio de Cloud Run. Visita esta URL en un navegador web (o usa una herramienta como curl) y observa cómo aumenta el recuento en tu instancia de Redis cada vez que se visita el servicio.