An application based on microservices is composed of small, highly decoupled, mostly autonomous components, that are built to offer a specific (mostly business) functionality. A cloud-native application is composed of multiple microservices that communicated through shared infrastructure, in most cases over HTTP/REST. The microservices architecture provides two major advantages: various components can be developed, deployed, monitored, and troubleshot independently, on a service-by-service basis, rather than dealing with the entire application. The second advantage is that a specific layer can be scaled independently by other layers. The underlying infrastructure can also be provisioned and changed independently and faster.
James Lewis and Martin Fowler definition: Microservice architectural style is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API.
A situation when we may benefit from splitting an application into separate services is when:
- Logic is loosely coupled
- Data models are different
- Data is generally independent
Service discovery is letting microservices know about each other in a dynamic environment. Service discovery addresses discovering the instances of a particular service, adding and removing service instances and handling the situation when a service instance becomes unresponsive, as indicated by a service health monitoring feature. The list of discrete features we would expect from a service discovery provider implementation is:
- The ability to register a service on service startup.
- The ability to deregister a service on shutdown.
- The ability to get a list of services, per type.
- Service health monitoring and automatic removal of inactive services.
In most cases, the service discovery function is implemented with a service registry.
Each service can either register itself, or use some library or tool to automatically register on startup. Once the service is registered, it is being monitored via health checks to ensure that is available.
Service Discovery Patterns
Client-Side Service Discovery
For client-side service discovery, the dependent service connects to the registry and pulls targets. The downside is that this makes the service logic more complex, and also burdens it with load balancing duties.
Server-Side Service Discovery
For server-side service discovery, the dependent service sends requests into a load balancer. The load balancer interacts with the registry and becomes informed on possible targets. The load balancer does the load balancing.
Service Discovery Solutions
Service Heath Monitoring
A registry keeps up to date with the health of the registered services via a pull model (the registry polls) or push model (the service pushes health information).
Synchronous communication is a way of interaction between network applications, in which applications exchange data using a request-response model. The client, which sent the request, blocks the invoking thread until a response is available, or an error or timeout occur. HTTP is one of many protocols that allow synchronous communication. gRPC is an alternative.
In most cases, Kubernetes is a good option.
Deployment Best Practices
A canary deployment is a special type of deployment where only a small fraction of the instances is updated. This allows testing the new version on a subset a production instances and quickly roll back if there are problems, without affecting a large user population.