This post describes some of the common considerations for developing microservices in Java and deploying the microservice on cloud containers offered by Google cloud (GCP), Amazon Web Services (AWS) and IBM cloud.
1. Microservices Considerations
a. Organizational Considerations
Organizations need to consider cultural changes that needed to support Micro-services ownership i.e. principle of product and not projects, lifetime ownership, DevOps culture etc.
b. Team Size
One team per microservice that covers all aspects for microservice delivery (includes Development manager, Development team, QA, DBA.). The team size shouldn’t be larger than what two pizzas can feed.
c. Design Principles
- Define microservices by following
- By Business Capability – Align with Business structure
- By Domain Driven Design – analyze the domain & discover entities, context map to define microservices.
- Microservices are developed as cloud native apps needs to follow 12 factor app principles (codebase, dependencies, configuration, backing services, build-release-run, processes, port binding , concurrency, disposability, dev/prod parity, logs, admin processes)
- Micro-service should follow following principles
- Single Responsibility Principle (SRP) – Do one thing & do it well
- Common Closure Principle (CCP) – Group related elements that change together in common place & should be released together.
- Single Page Application (SPA) – single web entry page that load once & update contents based on user interaction.
- Backend for Frontend (BFF) – Define different backend for each frontend client type.
d. Implementation Patterns
Following are some patterns that helps build resilient scalable microservices.
- Service Discovery – Dynamically discover services using service registry
- Service Invocation – Synchronous or asynchronous style
- Data Sharing across micro services – Pub/Sub mode or adapter service or data pump with eventual consistency
- Circuit Breakers –avoids cascading failures
- Timeouts – avoids unlimited waiting for resources , frees up resources, avoid bottlenecks if some components doesn’t respond by deadline
- Bulkhead & fallback – allows isolations of application so that if one fails other components will continue
- Versioning – allows changes to microservices when needed without breaking clients/consumers.
- Command Query Responsibility Segregation (CQRS) – decouple the queries & commands into separate operations.
e. Tools & Technology
Above diagram lists choice of some tools/technologies available based on Java/ Open Source can be used to develop micro services.
2. Microservices Architecture using Cloud Containers
Why Containers for microservices?
- Self-contained images that make sure no disparity between different environments
- Fine grained execution environment & Lightweight
- Better isolation
- Faster initiation & execution, scaling
Below is Example high level container architecture to deploy java micro services with SQL DB on cloud.
Following table shows components offered by Amazon, GCP, and IBM Cloud to realize above architecture.
3. Deploy java microservice Docker image to cloud container
High level flow above shows deployment of the microservice to container using CI/CD pipeline.
A typical CI/CD workflow follows these steps:
- Build Application — A change to the version control (ex. GitHub) of the application triggers a build. Resulting built jars/wars stored in the artifacts repository.
- Build Image — The CI Agent pulls the Dockerfile and associated files to build the image from version control. The Dockerfile is setup so that the artifact built-in the previous step is copied into the image.
- Deploy Image to Test environment — deploy the image for testing.
- Test Application — The CI Agent deploys a test container to test the application deployed in the previous step. If all of the tests pass, then the image can be signed with a QA
- Container registry – after successful testing push the application Docker image to container registry.
- Deploy to Prod or other environments higher environments.