In a real-world situation, due to various reasons like auto-scaling and fault tolerance mechanisms, often you will need to spin up and spin down various applications (containers). Because of this, their locations like IP addresses, Hostnames, etc may change. For this reason, DNS – with its time-to-live expiration values – may be a poor fit for service discovery and location. It is crucial to decouple the client applications from the location of the services; a little bit of indirection is required.
A Service Registry adds that indirection. A service registry is like a phonebook, letting clients look up services by their logical names and find the required location details like IP addresses or Hostnames. There are many such service registries available in today’s world, some common examples include Netflix’s Eureka, Apache Zookeeper, and Hashicorp Consul. ln a Microservices World, individual applications (Services) will read from a Service Registry to inquire where other services live. Spring Cloud’s DiscoveryClient abstraction provides a convenient client-side API implementation for working with all manner of service registries, be they Apache Zookeeper, Netflix Eureka, Hashicorp Consul, Etcd, Cloud Foundry, Lattice, etc. It’s easy enough to plugin other implementations since Spring is a framework and a framework is, to borrow the Eiffel definition, open for extension. Some of these words are copied from my fav. Josh Long.
This article is part of the previously discussed Microservices article, please go through the previous article if you have not.
What is Service Discovery Pattern?
Service Discovery Pattern is used in Microservices to find the individual service’s network locations e.g. IP address, Hostname, etc.
In a traditional monolithic application, services run in a specific fixed network location, so it is easy to keep track of these details. Other applications that need to communicate, can easily use the hard-coded fixed locations and invoke the services. However, in microservices there are multiple individual services, this number can go up to 1000. Each of these services will have dynamically assigned network addresses. Because of this, it is difficult to keep track of all these locations manually, therefore we make use of a special application that keeps track of the network locations of all these services which we call Service Registry.
Mostly there are 2 types of Service registration patterns and 2 types of Service Discovery Patterns that are discovered here:
- Self registration pattern or
3rd Party registration Pattern
- Client-side service discovery pattern
- Server-side service discovery pattern
Before understanding the above-discussed Service Discovery Patterns, it is important to understand a key component in the entire service discovery mechanism called Service Registry. I will not talk about the third-party registration pattern in this article as the tools like Netflix prana are not in active maintenance anymore and today there are no other clear alternatives for this.
What is a Service Registry?
A service registry is a database of all available service instances. It keeps the details of the currently-available instances of each service and their network details for establishing a connection.
Ideally, in microservices, each individual service is required to register itself into the Service Registry and provide the details for network connections. Other services will query the Service-registry to retrieve the details and then establish the connections with it. The registry also has additional mechanisms like checking the heartbeats of the services in certain intervals to see if the services are still up and running. If the status of a particular service is unhealthy, the registry will remove them from the healthy records list.
1. Self-registration Pattern
Registration pattern explains how individual services register their network locations in Service Registry. You need to apply either client-side service discovery patterns or Server-side discovery patterns to make the self-registration discovery pattern work.
- Each individual service registers on Service-Registry itself on startup so they can be discovered by other microservices. Registering means, it registers the service instance network location details like hostname, IP address, etc.
- Each service also unregisters itself on shutdown or on system crash.
- If because of some reason the service is busy and unable to process any incoming requests, then it also needs to unregister itself from the service registry.
As part of this Spring Cloud Microservices tutorial, we will use the Eureka Service Registry (as the registry) and Eureka Client @EnableEurekaClient in each individual service to get registered in the Eureka registry server.
2. Client-side service discovery
Before making a connection to another micro-service, the client app obtains the network location of the service instance by querying a Service Registry. As discussed earlier, the Service Registry knows the locations of all service instances and their respective network locations.
In this tutorial series, we will use
@EnableEurekaClient to make sure client-side service discovery is taken care of by the Netflix Eureka client. We will also configure the OpenFeign client to work with Eureka Client for automatic client-side service discovery. The client-side discovery comes with several advantages and disadvantages as discussed below.
- Client-side discovery is simple to implement and has fewer components to manage. Network lookup is also easy because of the use of the Service registry.
- This pattern couples the client code with the service registry, without a service registry we can not use this pattern.
- Each and every individual service need to have this implemented. Imagine you are using polyglot technologies for implementing the services, calling the service registry, and implementing the discovery mechanism can become challenging especially from a non-jvm-based language.
- The client service also has to make at least 2 calls to reach the target microservice. The network look-up call is usually cached for a certain duration to overcome this limitation.
We would be using client-side service discovery in this Spring cloud tutorial series.
3. Server-side discovery pattern
The client/consumer application does not require being aware of the service registry. The requests are made through a router, the router then searches the registry for destination service network locations. Once the router finds the requested service details from the registry, it forwards them to the consumer service. This router here is also known as a load balancer.
- The AWS Elastic Load Balancer (ELB) is an example of a server-side discovery router. It takes care of routing the incoming requests to the set of EC2 instances. ELB can route internal as well as external traffics depending on your configurations.
- In Kubernetes, you can use the inbuilt proxy to implement the server-side discovery pattern. Here is a reference link for the same.
Some of the advantages of using this:
- Client code is much simpler as it does not need to be registry aware. The router/load balancer lifts the heavy load of the network look up and talks to the service registry.
- If the cloud provider has a load balancer like AWS ELB, it becomes much easier. Else will have to go with third-party tools like Consul etc.
Some of the limitations of this approach:
- If the router is not part of the cloud environment, it can be complex to implement this.
- The router also needs to support various protocols like HTTP, gRPC, Thrift, etc.
- More network hops are required as compared to the client-side discovery mechanism.
We would be using Self-registration with a client-side discovery pattern. This means individual services will register themself on Service Registry. The registry-aware client present in each service will take care of fetching the network locations of destination services from the Service Registry whenever required. We would be using the Netflix Eureka registry server as well as the registry client in our tutorial.
Please share your feedbacks in the comments below.