Service discovery deals with the problems about how microservices talk to each other, i.e. perform API calls. In a traditional network topology, applications have static network locations. Hence IP addresses of relevant external locations can be read from a configuration file, as these addresses rarely change.
In a modern microservice architecture, knowing the right network location of an application is a much more complex problem for the clients as service instances might have dynamically assigned IP addresses. Moreover the number instances may vary due to autoscaling and failures.
Hence, service discovery tools and patterns are developed to overcome these challenges. Mainly service discovery consists of a key-value store (Service Registry) and an API to read from and write to this store. New instances of applications are saved to this service registry and deleted when the service is down or not healthy. Clients, that want to communicate with a certain service are supposed to interact with the service registry to know the exact network location(s).
There are two main service discovery patterns that shape how clients interact with other services:
- Client-Side discovery pattern: Client talks directly with the service registry to receive the IP addresses of a certain service and uses its own load balancing algorithm to choose one of them. Although this approach is simple and straigtforward, it couples service discovery logic with clients.
- Server-Side discovery pattern: Client makes requests to a load balancer or an API gateway, which routes the requests to corresponding services. In this case API gateway is aware of the service registry and load balancing, which leaves clients abstracted from the service discovery logic. Maintaining a single point of failure API gateway is the main drawback of this approach.
Consul, Netflix Eureka, etcd, Apache Zookeeper are some of the most popular service discovery tools that are widely used and compatible with many platforms.