Table of Contents
- 1. Introduction
- 2. Prerequisites
- 3. Step1: Set up Google Cloud Memorystore
- 4. Step2: Configure Serverless VPC Access
- 5. Step3: Create the Golang App
- 6. Step4: Deploy the App
- 7. Test Locally
- 8. Conclusion
1. Introduction
In this tutorial, we will be building a Golang based Google App Engine application that integrates with Google Cloud Memorystore. Our app will count visitors using GAE app as frontend and Redis memorystore as cache.
2. Prerequisites
We will be using:
- GCP project with billing enabled
- Google Cloud SDK installed and initialized
- Golang 1.11 or later
- A Redis instance in Google Cloud Memorystore
- App Engine standard environment for Go
3. Step1: Set up Google Cloud Memorystore
- Enable the APIs:
PROJECTID=golang-memorystore-app-project-id
REGION=us-central1
REDIS_INSTANCE_NAME=my-redis-instance
gcloud config set project $PROJECTID
gcloud services enable redis.googleapis.com
gcloud services enable appengine.googleapis.com
- Create a Redis instance:
gcloud redis instances create $REDIS_INSTANCE_NAME \
--size=1 \
--region=$REGION
- Note the Redis instance connection details, including the
host
andport
andnetwork
fields under thegcloud redis instances describe
command.
gcloud redis instances describe my-redis-instance \
--region=$REGION
Memorystore doesn’t require authentication by default, so we won’t need a password.
4. Step2: Configure Serverless VPC Access
We don’t want our Redis instance to be publicly accessible. Therefore, we will set up a Serverless VPC Access connector to allow our App Engine application to connect to the Redis instance privately.
- Create a Serverless VPC Access connector:
gcloud compute networks vpc-access connectors create my-connector \
--region=us-central1 \
--subnet-project=my-project \
--subnet=default \
--machine-type=e2-micro \
network=default \
--range=10.8.0.0/28
- Update the
app.yaml
to include the connector:
runtime: go113
env: standard
vpc_access_connector:
name: projects/my-project/locations/us-central1/connectors/my-connector
egress_settings: ALL_TRAFFIC
env_variables:
REDIS_HOST: 'my-redis-instance'
REDIS_PORT: '6379'
5. Step3: Create the Golang App
Create a file named main.go
and add the following code:
mkdir golang-memorystore-app
cd golang-memorystore-app
go mod init golang-memorystore-app
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 counter", http.StatusInternalServerError)
return
}
fmt.Fprintf(w, "Visitor number: %d", counter)
}
func main() {
redisHost := os.Getenv("REDIS_HOST")
redisPort := os.Getenv("REDIS_PORT")
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("Server starting on port %s\n", port)
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), nil))
}
6. Step4: Deploy the App
- Deploy the application to App Engine:
export GOOGLE_APPLICATION_CREDENTIALS="/path/to/your-service-account.json"
gcloud auth activate-service-account --key-file=$GOOGLE_APPLICATION_CREDENTIALS
gcloud config set project my-project-id
gcloud app deploy
- Visit the app:
Once deployed, you can navigate to https://<golang-memorystore-app-project-id>.appspot.com
to see the visitor count in action.
7. Test Locally
For local development, you can run Redis locally using Docker:
docker run -p 6379:6379 -d redis
Then, set the environment variables and run the app:
export REDIS_HOST=localhost
export REDIS_PORT=6379
go run main.go
Thereby, you can aceess the application at http://localhost:8080.
8. Conclusion
In this tutorial, we have successfully set up a Golang application on Google App Engine that connects to Google Cloud Memorystore using Redis.