Skip to content
Anil Kumar GOTTAM edited this page Jul 13, 2020 · 13 revisions

Microservice Architecture with Azure Spring Cloud

Summary

Microservices architecture infrastructure is simplified with fully-managed Azure Spring Cloud. Bundled with Service Registry, Config Server, Scaling, Load Balancing, Distributed Tracing, Blue-Green Deployment etc.

We just focus on creating 3 services User Directory, Search Directory, Gateway.

  • User Directory Service - Kotlin-Based Spring Boot App, Gradle Build

    • Admin API to perform Search, Soft & Perm Delete of Users from Postgres
  • Search Directory Service - Java-Based Spring Boot App, Maven Build

    • Search API to perform Search
      • Used Feign Client to consume 'api/users'
      • Ideal use-case to be Azure Postgres Replica, Azure Cache for Redis
  • Gateway Service - Java-Based Spring Boot App, Maven Build

    • Publicly Exposed
    • Routing
    • Static Content

Key Takeaways

  • Resource Group
  • Azure Spring Cloud
  • App Services
  • Azure Database for PostgreSQL Server
  • Distributed Tracing
  • Scaling

Skip to Readymade Artefacts If you just want to focus on Azure Spring Cloud Setup and Deploy Apps. Otherwise, Continue for detailed steps to do practical along.

Azure Resources Creation (One Time Setup)

SUBSCRIPTION_ID=<YOUR_SUBSCRIPTION_GUID>
RESOURCE_GROUP_NAME=azsc-from-paloit-group
SPRING_CLOUD_NAME=azsc-from-paloit
REGION_NAME=eastus

# Set Account Subscription
az account set --subscription "$SUBSCRIPTION_ID"
  • Azure Resource Group

az group create -g "$RESOURCE_GROUP_NAME" -l "$REGION_NAME"
  • Azure Spring Cloud Instance

az spring-cloud create -g "$RESOURCE_GROUP_NAME" -n "$SPRING_CLOUD_NAME"
  • Azure Spring Cloud Config Server

Use Azure Web Portal to map Github repo azsc-config-server to the config server

For Simplicity, I've generated config-server-import.yml file where we'll mention SpringCloudConfigServerGit-Uri, username, and password (Github PAT) and import this in Azure Web Portal under Spring Cloud > Config Server

For now, we can make azsc-config-server repository as a Private repository. Irrespective of it, any sensitive data to be stored in Azure Key Vault.

  • Azure Database for PostgreSQL Server

AZ_POSTGRES_SERVER=azsc-postgres-server
AZ_POSTGRESQL_ADMIN_USER=postgres
AZ_POSTGRESQL_ADMIN_PASSWORD=Im4mPalo#
AZ_DATABASE_NAME=azsc-demo
AZ_POSTGRES_REPLICA_SERVER=azsc-search-directory-replica

# (Optional) http://whatismyip.akamai.com/
AZ_LOCAL_IP_ADDRESS=183.83.240.53

# Create Postgres Server (Basic, Gen 5, Core 1)
az postgres server create \
    --resource-group $RESOURCE_GROUP_NAME \
    --name $AZ_POSTGRES_SERVER \
    --location $REGION_NAME \
    --sku-name B_Gen5_1 \
    --storage-size 5120 \
    --admin-user $AZ_POSTGRESQL_ADMIN_USER \
    --admin-password $AZ_POSTGRESQL_ADMIN_PASSWORD \
    | jq

# (Optional) Create Firewall Rule to connect from Local Machine
az postgres server firewall-rule create \
    --resource-group $RESOURCE_GROUP_NAME \
    --name $AZ_POSTGRES_SERVER-database-allow-local-ip \
    --server $AZ_POSTGRES_SERVER \
    --start-ip-address $AZ_LOCAL_IP_ADDRESS \
    --end-ip-address $AZ_LOCAL_IP_ADDRESS \
    | jq

# Create A Database in Postgres Server
az postgres db create \
    --resource-group $RESOURCE_GROUP_NAME \
    --name $AZ_DATABASE_NAME \
    --server-name $AZ_POSTGRES_SERVER \
    | jq

# Disable SSL and Allow Apps to Access Postgres from Azure Web Portal
Screenshot [WIP]
  • Azure Database for Postgres Read Replica Server

# (Optional) without this step, demo can be finished 
az postgres server replica create --name $AZ_POSTGRES_REPLICA_SERVER --source-server $AZ_POSTGRES_SERVER --resource-group $RESOURCE_GROUP_NAME

az postgres server replica list --server-name $AZ_POSTGRES_SERVER --resource-group $RESOURCE_GROUP_NAME

Azure Resource Creation (As Per Microservices)

  • Azure App Service - User Directory Service

az spring-cloud app create -n azsc-user-directory-service
  • Azure App Service - Search Directory Service

az spring-cloud app create -n azsc-search-directory-service
  • Azure App Service - Gateway

az spring-cloud app create -n azsc-gateway --is-public true

Develop Spring Boot Application (without Spring Cloud)

e.g. for azsc-user-directory-service

Gradle

https://start.spring.io/#!type=gradle-project&language=java&platformVersion=2.3.1.RELEASE&packaging=jar&jvmVersion=1.8&groupId=com.prototype&artifactId=azsc-user-directory-service&name=azsc-user-directory-service&description=&packageName=com.prototype.userdirectory&dependencies=web,postgresql,data-jpa

Maven

https://start.spring.io/#!type=maven-project&language=java&platformVersion=2.3.1.RELEASE&packaging=jar&jvmVersion=1.8&groupId=com.prototype&artifactId=azsc-user-directory-service&name=azsc-user-directory-service&description=&packageName=com.prototype.userdirectory&dependencies=web,postgresql,data-jpa

Build Microservices (with Spring Cloud Dependencies and Azure Spring Cloud Client dependency)

  • Spring Cloud Dependencies

Gradle

implementation("org.springframework.cloud:spring-cloud-starter-config")
implementation("org.springframework.cloud:spring-cloud-starter-netflix-eureka-client")

Maven

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
  • Conditional Dependency (with cloud profile)

This to connect your microservice seamlessly, securely with fully managed Spring Cloud Discovery Server and Spring Cloud Config Server.

Gradle [WIP Profile Syntax]

implementation("com.microsoft.azure:spring-cloud-starter-azure-spring-cloud-client:2.2.0")

Maven

<profiles>
	<profile>
		<id>cloud</id>
		<dependencies>
			<dependency>
				<groupId>com.microsoft.azure</groupId>
				<artifactId>spring-cloud-starter-azure-spring-cloud-client</artifactId>
				<version>2.2.0</version>
			</dependency>
		</dependencies>
	</profile>
</profiles>

Deploy Microservices to Azure Spring Cloud (--verbose)

  • Deploy to Azure Spring Cloud

az spring-cloud app deploy -n azsc-user-directory-service --jar-path <PATH_TO_JAR_FOLDER>/azsc-user-directory-service-0.0.1-SNAPSHOT.jar
az spring-cloud app deploy -n azsc-search-directory-service --jar-path <PATH_TO_JAR_FOLDER>/azsc-search-directory-service-0.0.1-SNAPSHOT.jar
  • <PATH_TO_JAR_FOLDER>
  • Maven your-service/target
  • Gradle your-service/build/libs
  • Test Microservices with Private URLs

  • Watch Logs

az spring-cloud app logs --name azsc-user-directory-service --resource-group "$RESOURCE_GROUP_NAME" --service "$SPRING_CLOUD_NAME" -f

Build & Deploy Gateway

  • Build Gateway (with cloud profile)

In addition to Spring Cloud Dependencies and Azure Spring Cloud Client dependency, add Gateway from Spring Cloud as below

Gradle

implementation("org.springframework.cloud:spring-cloud-starter-gateway")

Maven

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

Also, make sure below the property is added to application.properties, this is to configure Spring Cloud Gateway to use the Spring Cloud Service Registry to discover the available microservices

spring.cloud.gateway.discovery.locator.enabled=true

Additionally, if you want custom routings can be added to azsc-gateway.yml and reference here spring-cloud-gateway

  • Deploy Gateway to Azure Spring Cloud

az spring-cloud app deploy -n azsc-gateway --jar-path <PATH_TO_JAR_FOLDER>/azsc-gateway-0.0.1-SNAPSHOT.jar
  • Test Microservices with Public (Gateway) URLs

Distributed Tracing

Add Zipkin Dependency to All Microservices including Gateway and Redeploy

Gradle

implementation("org.springframework.cloud:spring-cloud-starter-zipkin")

Maven

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

Scaling

If we don't mention the deployment name (-d DDDDD), default is production.

az spring-cloud app scale -n <YOUR_APP> -s $SPRING_CLOUD_NAME -g $RESOURCE_GROUP_NAME --cpu 2 --memory 4

az spring-cloud app scale -n <YOUR_APP> -s $SPRING_CLOUD_NAME -g $RESOURCE_GROUP_NAME --instance-count 2
  • <YOUR_APP>
  • azsc-user-directory-service
  • azsc-user-search-service

Cleanup Resources

az group delete --name $RESOURCE_GROUP_NAME --yes
Clone this wiki locally