Build Scalable Java Microservices With Spring Boot And Spring Cloud On Gcp

Cui Cui Follow Sep 10, 2023 · 9 mins read
Share this

Source code

git clone https://github.com/saturnism/spring-cloud-gcp-guestbook.git

export PROJECT_ID=$(gcloud config list --format 'value(core.project)')
gcloud config list --format 'value(core.project)'
gsutil ls gs://$PROJECT_ID
gsutil -m cp -r gs://$PROJECT_ID/* ~/

Bring to local

# Create GCP service-account
gcloud iam service-accounts create guestbook
# Assign Editor role to service-account
gcloud projects add-iam-policy-binding ${PROJECT_ID} --member serviceAccount:guestbook@${PROJECT_ID}.iam.gserviceaccount.com --role roles/editor
# Create service-account key file
gcloud iam service-accounts keys create ~/service-account.json --iam-account guestbook@${PROJECT_ID}.iam.gserviceaccount.com


gcloud auth login
gcloud config configurations list
gcloud config configurations create guestbook
gcloud config configurations activate guestbook
gcloud config set compute/region europe-west2
gcloud config set compute/zone europe-west2-b
gcloud config set project qwiklabs-gcp-03-f61e7813f2e5

/Users/zcui/Library/Application Support/google-cloud-tools-java/managed-cloud-sdk/downloads/google-cloud-sdk.tar.gz

Day 1

  • GCP CloudSQL

Spring Cloud Tech Learned:

Side tools

GCP CloudSQL + Spring Cloud GCP SQL

gcloud services list
gcloud services enable sqladmin.googleapis.com

gcloud sql instances list
gcloud sql instances create guestbook --region=europe-west2
gcloud sql instances describe guestbook --format=value(connectionName)

gcloud sql databases create messages --intance guestbook

gcloud sql connect guestbook

show databases;
use messages;
show tables;

CREATE TABLE guestbook_message (
  id BIGINT NOT NULL AUTO_INCREMENT,
  name CHAR(128) NOT NULL,
  message CHAR(255),
  image_uri CHAR(255),
  PRIMARY KEY (id)
);

./mvnw -q spring-boot:run -Dspring-boot.run.jvmArguments="-Dspring.profiles.active=cloud"

curl -XPOST -H "content-type: application/json" \
  -d '{"name": "Ray", "message": "Hello CloudSQL"}' \
  http://localhost:8081/guestbookMessages

curl http://localhost:8081/guestbookMessages

Day 2

  • GCP Runtime Configuration api
  • GCP Cloud Trace api

Spring Tech ToLearn:

bootstrap.properties that disables the Spring Cloud GCP starter

GCP RuntimeConfig + Spring Cloud Config

# Enable GCP runtime configuration api
gcloud services enable runtimeconfig.googleapis.com
# Create GCP runtime configuration for local profile
gcloud beta runtime-config configs create frontend_local
# Set a variable in config file
gcloud beta runtime-config configs variables set greeting "Hi from Runtime Config" --config-name frontend_local
# List a variable in config file
gcloud beta runtime-config configs variables list --config-name=frontend_local
# Get a variable in config file
gcloud beta runtime-config configs variables get-value greeting --config-name=frontend_local
# Set new value to variable in config file
gcloud beta runtime-config configs variables set greeting "Hi from Updated Config" --config-name frontend_local

# Hot reload the config to the application
curl -XPOST http://localhost:8080/actuator/refresh
# Check application properties through Spring Boot Actuator
curl http://localhost:8080/actuator/configprops | jq

GCP Cloud Trace + Spring Cloud GCP Trace

export PROJECT_ID=$(gcloud config list --format 'value(core.project)')

# Enable GCP CloudTrace api
gcloud services enable cloudtrace.googleapis.com
# Create GCP service-account
gcloud iam service-accounts create guestbook
# Assign Editor role to service-account
gcloud projects add-iam-policy-binding ${PROJECT_ID} --member serviceAccount:guestbook@${PROJECT_ID}.iam.gserviceaccount.com --role roles/editor
# Create service-account key file
gcloud iam service-accounts keys create ~/service-account.json --iam-account guestbook@${PROJECT_ID}.iam.gserviceaccount.com

# Run application with service-account key
./mvnw spring-boot:run -Dspring-boot.run.jvmArguments="-Dspring.profiles.active=cloud -Dspring.cloud.gcp.credentials.location=file:///$HOME/service-account.json"

Day 3

Objectives

Objectives 1 - GCP Cloud Pub/Sub api

  • In this lab, you learn how to perform the following tasks:
  • Enable Cloud Pub/Sub and create a Cloud Pub/Sub topic
  • Use Spring to add Cloud Pub/Sub support to your application
  • Modify an application to publish Cloud Pub/Sub messages
  • Create a Cloud Pub/Sub subscription
  • Modify an application to process messages from a Cloud Pub/Sub subscription

Objectives 2 - Spring Integration

  • Add Spring Integration Core to an application
  • Create an outbound message gateway in your application
  • Configure an application to publish messages through a gateway
  • Bind the output channel of a message gateway to Cloud Pub/Sub

Objectives 3 - GCP Cloud Storage api

  • Add the Spring starter for Cloud Storage
  • Create a Cloud Storage bucket
  • Modify the HTML template of the frontend application to enable file uploads
  • Modify the frontend application to process and store images on Cloud Storage
  • Modify the frontend application to display uploaded message images

Objectives 4 - GCP Vision API

  • Add a GCP API Java library to an application
  • Create a GCP credential scope for Spring
  • Create a Java bean that implements Vision API features
  • Use Vision API to add image analysis to an application

Objectives 5 - GCP Serverless AppEngine

  • Initialize App Engine
  • Reconfigure an application to work with App Engine
  • Configure the Cloud Runtime Runtime Configuration API to automatically provide the backend URL to the Frontend application
  • Deploy the application to App Engine

Spring SDK

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-gcp-starter-storage</artifactId>
</dependency>

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-gcp-starter-vision</artifactId>
</dependency>

<plugin>
  <groupId>com.google.cloud.tools</groupId>
  <artifactId>appengine-maven-plugin</artifactId>
  <version>2.2.0</version>
  <configuration>
    <version>1</version>
    <deploy.projectId>GCLOUD_CONFIG</deploy.projectId>
    </configuration>
</plugin>

CLIs

GCP Cloud PubSub

gcloud services enable pubsub.googleapis.com

gcloud pubsub topics create messages
gcloud pubsub subscriptions create messages-subscription-1 --topic=messages
# The message remains in the subscription until it is acknowledged.
gcloud pubsub subscriptions pull messages-subscription-1
# Pull the message again and remove it from the subscription by using the auto-acknowledgement switch at the command line.
gcloud pubsub subscriptions pull messages-subscription-1 --auto-ack

# Initiate SpringBoot project
curl https://start.spring.io/starter.tgz -d dependencies=web,cloud-gcp-pubsub -d baseDir=message-processor | tar -xzvf -

GCP Visioning API

gcloud services enable vision.googleapis.com

gcloud app browse -s guestbook-service

GCP App Engine

gcloud app create --region=europe-west2

gcloud app browse
gcloud app browse -s guestbook-service
gcloud app logs tail -s guestbook-service

Spring Tech ToLearn:

Samples:

Day 4

Objectives

Objective 1 - GCP Cloud Debugger

  • Configure Cloud Logging for an App Engine application
  • Configure Cloud Debugger source content for App Engine debugging
  • Configure Cloud Debugger logpoints and snapshots
  • Enable Cloud Monitoring

Objective 2 - GCP Cloud Spanner

  • Create a Cloud Spanner instance and database
  • Use the data definition language (DDL) to create a Cloud Spanner table
  • Use Spring to add support for Cloud Spanner to an application
  • Modify a Java application to use Cloud Spanner instead of Cloud SQL

Objective 3 - GCP Kubernetes

  • Create a Kubernetes Engine cluster
  • Create a containerized version of a Java application
  • Create a Kubernetes deployment for a containerized application

Objective 4 - GCP Kubernetes Monitoring (Prometheus)

  • Enable Cloud Monitoring for Kubernetes Engine
  • Enable Prometheus monitoring in a Kubernetes Engine cluster
  • Expose Prometheus metrics from inside a Spring Boot application
  • Explore live application metrics using Cloud Monitoring

CLIs

GCP GitRepo

gcloud beta debug source upload --project=qwiklabs-gcp-04-cbf6d2d0d399 --branch=4026E982E356B8AFF02C LOCAL_PATH

gcloud services enable sourcerepo.googleapis.com
gcloud source repos create google-source-captures

git config --global user.email $(gcloud config get-value core/account)
git config --global user.name "devstar"

gcloud beta debug source upload --project=$PROJECT_ID \
 --branch=4026E982E356B8AFF02C ./src/

GCP Spanner

gcloud services enable spanner.googleapis.com
gcloud spanner instances create guestbook --config=regional-us-central1 --nodes=1 --description="Guestbook messages"
gcloud spanner databases create messages --instance=guestbook
gcloud spanner databases list --instance=guestbook

cd ~/guestbook-service
mkdir db
# spanner.ddl
CREATE TABLE guestbook_message (
    id STRING(36) NOT NULL,
    name STRING(255) NOT NULL,
    image_uri STRING(255),
    message STRING(255)
) PRIMARY KEY (id);

gcloud spanner databases ddl update messages --instance=guestbook --ddl="$(<~/guestbook-service/db/spanner.ddl)"
gcloud spanner databases execute-sql messages --instance=guestbook --sql="SELECT * FROM guestbook_message WHERE name = 'Ray'"

GCP K8s

# Enable service
gcloud services enable container.googleapis.com
# Create cluster
gcloud container clusters create guestbook-cluster \
    --zone=us-central1-a \
    --num-nodes=2 \
    --machine-type=n1-standard-2 \
    --enable-autorepair \
    --enable-stackdriver-kubernetes
# check k8s version
kubectl version

# Enable container registry
gcloud services enable containerregistry.googleapis.com
# Project info
export PROJECT_ID=$(gcloud config list --format 'value(core.project)')
echo $PROJECT_ID
# Project maven build plugin
<plugin>
    <groupId>com.google.cloud.tools</groupId>
    <artifactId>jib-maven-plugin</artifactId>
    <version>2.4.0</version>
    <configuration>
        <to>
        <!-- Replace [PROJECT_ID]! -->
        <image>gcr.io/[PROJECT_ID]/guestbook-frontend</image>
        </to>
    </configuration>
</plugin>
# Project container build
./mvnw clean compile jib:build

# Create service-account
gcloud iam service-accounts create guestbook
# Binding project role to account
gcloud projects add-iam-policy-binding ${PROJECT_ID} --member serviceAccount:guestbook@${PROJECT_ID}.iam.gserviceaccount.com --role roles/editor
# Create credentials of the account
gcloud iam service-accounts keys create ~/service-account.json --iam-account guestbook@${PROJECT_ID}.iam.gserviceaccount.com
# Create K8s secret with above credential
kubectl create secret generic guestbook-service-account --from-file=$HOME/service-account.json
# Verify k8s secret created
kubectl describe secret guestbook-service-account
watch kubectl get pods

K8s Prometheus

gcloud container clusters get-credentials guestbook-cluster --zone=us-central1-a
kubectl apply -f https://raw.githubusercontent.com/coreos/prometheus-operator/v0.38.1/bundle.yaml

cd ~/prometheus
export PROJECT_ID=$(gcloud config list --format 'value(core.project)')
echo $PROJECT_ID

cat prometheus.yaml | envsubst | kubectl apply -f -
kubectl apply -f pod-monitors.yaml

Spring SDK

# Spanner
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-gcp-starter-data-spanner</artifactId>
</dependency>
# Prometheus
<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
     <groupId>io.micrometer</groupId>
     <artifactId>micrometer-registry-prometheus</artifactId>
     <scope>runtime</scope>
</dependency>

# Spanner
spring.cloud.gcp.spanner.instance-id=guestbook
spring.cloud.gcp.spanner.database=messages
# Prometheus
management.server.port=9000
management.endpoints.web.exposure.include=*



# logback-spring.xml
<configuration>
    <include resource="org/springframework/boot/logging/logback/defaults.xml" />
    <include resource="org/springframework/boot/logging/logback/console-appender.xml" />

    <springProfile name="cloud">
        <include resource="org/springframework/cloud/gcp/logging/logback-json-appender.xml"/>
        <root level="INFO">
            <appender-ref ref="CONSOLE_JSON"/>
        </root>
    </springProfile>
    <springProfile name="default">
        <root level="INFO">
            <appender-ref ref="CONSOLE"/>
        </root>
    </springProfile>
</configuration>

Spring Tech ToLearn:

Join Newsletter
Get the latest news right in your inbox. We never spam!
Cui
Written by Cui Follow
Hi, I am Z, the coder for cuizhanming.com!