December 30, 2019 Cloud Native Patterns
“We’re drifting towards a cloud native era” – Jessica Deen, Microsoft
In this article, we talk about cloud native patterns. The reader will learn how to create cloud native applications. In this series so far, we looked at cloud native – simple definition and cloud native building blocks.
Monolith architecture was the traditional style used in architecting applications with multiple layers mentioned below :
- Business Rules
- Business Logic
- Data Access
Monolithic architecture created tight coupling and maintenance of the application was challenging. The fear cycle comes up regarding the changes in monolithic applications. The cost implications are huge in the case of these types of apps. Managing new modules and handling complex modules in the system was a big concern. Migrating them to a new technology stack was always an issue. The process methodologies were waterfall-based so that new agile methods were not suitable for enhancing the application. The application code has architectural erosion because of architecturally significant use cases.
Web 2.0 helped in resolving this complex architectural erosion problem in enterprises. A new trend called “cloud native” emerged. Service-oriented architecture style was another trend that helped to create services for key modules. The microservices architectural style emerged and these were containerized. Cloud native applications are microservices-based and built in a container environment. Containers came in around the 2000s, with Linux & open VZ containers becoming the first in the market. Docker is based on Linux containers and was released in 2013. Many other containers such as Nomad, Mesos, Swarm, and Kubernetes emerged in the market.
Cloud native applications consist of microservices which are not tightly coupled and help in delivering business value. These applications can be modified and enhanced easily. Elastic infrastructure on clouds makes these applications scalable. DevOps processes help in deployment and maintaining good quality.
Container-based applications help with application management and consistent infrastructure. The use of multiple technology stacks and programming languages is easy with containers. Resources can be managed easily on a requirement basis. Pipelines in DevOps tools help in continuous deployments and build management.
Cloud native patterns help in using the best practices for building the containerized applications. These patterns are categorized into five important areas mentioned below:
- Application Design
- Networking & Communication
- Architectural Concerns
The patterns under different categories are shown in the diagram above. The list of the patterns covered in different categories is below.
- Domain Driven Design
- Bounded Context principles
- Event Driven vs Request & Response vs CQRS
- Managing Multiple Services Instances
- Scaling up/down (Horizontally/instant)
- Stateful and Stateless services
- Configuration externalized
- Upgrades with no down time
- Load balancing (client & server side)
- Service Registry
- API Gateway
- Service Mesh
- Distributed tracing
- 12 Factors
API Gateway and service registry are important in building an application. Gateway helps in abstracting the microservices details and microservices can be enhanced easily without affecting the consumer of the API. The service registry helps in the discovery of the services. The scaling of the system will be dynamic. The elastic infrastructure helps in increasing and decreasing the number of nodes.
The system needs to be resilient and reliable. The engineering teams will be using DevOps tools and agile methodology. Teams should be able to handle chaos and manage it through the agile principles of the test early and quality always mindset. Engineering and application runtime metrics are important during the application lifecycle.
The twelve factors pattern is based on application development methodology which focuses on the following factors.
- Backing services
- Build, release, run
- Process methodology
- Port binding
- Dev/prod parity
A codebase needs to be maintained and software needs to be checked in for version control. Dependencies need to be defined and managed. The configuration of the application needs to be well defined. Backing services will be the resources of the system. Building and execution need to be separated. The application needs to be run as a stateless process. The system should be scalable and manageable regarding startup & shutdown. The goal is to have different stages such as dev, testing, staging, and production run similarly. The logging needs to be event stream pattern-based.
Applications need to be portable by having capabilities such as multi-location deployment, multi-environment deployment, continuous integration, continuous delivery, continuous improvement, and continuous performance. Containerized applications need to have builds isolated and elastic (every build has a container agent managing the resources).
The best practices regarding code pipelines include having a version controlling the pipeline definition. Each microservice will have a separate code repo and a pipeline. The pipeline tracks the modifications and enables the traceability of the requirements. The base images like Docker and AMI need to be separate for each microservice. Blue-green or hot deployment environment news needs to be available for immediate rollback. Feature toggles are suggested in order to handle requirements that are broken.
In the next part of the series, we will look at topics such as twelve-factor apps, data management and migration from monolithic to cloud-native applications.