Cloud Computing, Virtualisation, and Microservices
Cloud computing outsources hosting to shared infrastructure. Virtualisation multiplexes physical hardware. Microservices decompose applications into independently deployable units. Each adds capability and complexity.
Cloud Computing
Cloud computing outsources the hosting of applications to infrastructure managed by a third party. The motivation: physical servers are expensive to provision, maintain, and scale. Cloud providers offer on-demand resources, metered billing, and global reach.
A load balancer distributes incoming traffic across multiple servers. This prevents any single server from being overloaded. Common distribution strategy: round-robin or weighted round-robin, routing each request to the next available server.
Single point of failure (SPOF): if a single load balancer handles all traffic and fails, the entire application becomes unavailable. The solution is to run multiple load balancer instances, but this introduces coordination complexity.
Cloud computing does not eliminate hardware limitations. It relocates them and makes them elastic.
Virtualisation
A hypervisor runs on physical hardware and creates multiple isolated virtual machines (VMs), each with its own OS. Each VM believes it has exclusive access to CPU, memory, and storage.
Types of hypervisor:
- Type 1 (bare metal): runs directly on hardware (VMware ESXi, Hyper-V, KVM).
- Type 2 (hosted): runs on top of a host OS (VirtualBox, VMware Workstation).
Virtualisation allows:
- Dynamic allocation of resources (CPU, memory) to VMs based on current demand.
- Running multiple OSes on the same hardware.
- Isolation between tenants on shared infrastructure.
IaaS, PaaS, SaaS
| Model | What is managed by provider | Examples |
|---|---|---|
| IaaS (Infrastructure as a Service) | Hardware, networking, storage | AWS EC2, Google Compute Engine, Azure VMs |
| PaaS (Platform as a Service) | OS, runtime, middleware | Heroku, Google App Engine |
| SaaS (Software as a Service) | Everything | Gmail, Salesforce |
IaaS gives maximum control but requires managing the OS and everything above it. PaaS abstracts the platform but limits customisation. SaaS is entirely managed.
Containerisation
Containers package an application with its dependencies into a single deployable unit. Unlike VMs, containers share the host OS kernel. This makes them lighter, faster to start, and more portable.
A container is smaller than a VM: the unit of deployment can be a single microservice with a specific function (a database adapter, an email sender, an API gateway). This allows going from monolithic deployments to fine-grained services.
Horizontal Scaling and Database Replication
Horizontal scaling adds more servers rather than upgrading existing ones. A load balancer distributes traffic across the pool. The challenge is stateful data: if each server has its own database, data diverges.
Database replication solves this by maintaining copies of the database on multiple nodes:
- All nodes receive the same writes (synchronous or asynchronous).
- If one node goes down, another can serve reads.
- Duplicate data increases storage cost but improves availability.
The trade-off: replication adds latency to writes (especially synchronous replication) but improves read throughput and fault tolerance.
Microservices
A monolithic application is built as a single deployable unit. A microservices architecture decomposes the application into independently deployable services, each with a specific business responsibility.
Advantages:
- Independent scaling and deployment.
- Technology heterogeneity (each service can use a different stack).
- Fault isolation.
Problems:
- Complexity increases significantly.
- Testing requires more infrastructure (service mocks, integration environments).
- Transient network errors between services must be handled explicitly.
- Latency between services adds up.
- Security: inter-service communication needs authentication and authorisation.
Anti-patterns:
- All microservices calling each other directly (becomes a web of dependencies).
- Chatty communication patterns (too many small requests).
- Distributed monolith: services that cannot be deployed independently despite being separate.
Good practices: use a service mesh or API gateway for inter-service communication, CI/CD pipelines for each service, domain-driven design to define service boundaries, and health checks for every service.