Communication Among App Layers
For fulfilling any business functionality, applications either talk to different applications or application’s component talk among themselves.
E.g. Buying a product online, involves the retail application talking to the vendor’s inventory application, payment provider application, order application etc. And within the application, UI component talks to API layer which talks to data access layer.
In essence, the components talk to each other and hence need to know their address to talk to them.
Lets explore how the communication among the application has evolved and can be done.
It began with speaking to the application on IP and port. e.g. 18.104.22.168 : 8080
Then it evolved to a DNS, which added an ability to use easy to understand names mapped with the IP or its range.
This setup was fine until application reaches production but in production environment there needed at-least two servers for serving the traffic.
These servers would get equal load to serve and in case of failure of one instance the other instance would serve.
To enable this, load balancer came into picture. The overall structure though was hardwired. Any setup or application hosting change would require involvement of development team, operation team and the transition (sometimes) used to take toll on up time of the system.
With this approach, two of key business needs are impacted. Those are zero downtime with ability to add features/functions in the form of new services and consume those immediately by live system/traffic.
With micro-services world there are many independent services deployed and with new features coming in new services would arrive in the ecosystem.
Also with the use of cloud technology and its elasticity, the instances are created dynamically to serve the business. In such cases the address of individual service instances may change.
In the micro-services world, it is an essential aspect that services (once are up and ready for serving) should announce their presence to other services.
Service Registration & Discovery
This is because of the distributed nature of micro-services. Completing one business function spreads across multiple micro-services calling each other.
The phenomena of services being observable in order to discover and consume is called as service discovery.
Since micro-services are independent and autonomous, there requires a mechanism which facilitates service discovery across all services in the ecosystem.
Service discovery can be thought as a telephone directory. Lets say product booking service wants to call the vendor’s inventory service then it looks up to the service discovery, obtains the address and calls the respective service, instead of calling it directly and storing its address with itself.
Here is how service discovery mechanism works.
A micro-services when wants to announce itself to the world, registers itself with a service-discovery. Service discovery essentially is a central store of service’s addresses. Micro-services talk to the service discovery store and update their presence with address. This aspect is called as service registration.
A micro-service which wants to talk to another micro-service then it calls the central store of the service discovery requesting address of the respective service. Service discovery mechanism then resolves to the physical address of the service and sends the request. This mechanism is called service resolution.
In order to have a successful and effective implementation of this mechanism, there are multiple things to consider.
- Services must send health check messages to the central store to inform that its alive and can serve customers. Service instances not sending such health-check pings are considered unavailable.
- Mechanism should act as a load balancer to distribute the load to multiple instances of the service appropriately. It may use one of the various algorithms to distribute the requests (round robin, least connection etc).
There are primarily two ways to implement the discovery, depending on who takes the responsibility to talk to service-discovery store.
Server side discovery: The client makes a request to a service via a load balancer. The load balancer queries the service registry and routes each request to an available service instance.
AWS ELB is an example of server side discovery.
Client side discovery: Client takes the responsibility to talk to the service registry, fetches the addresses of the desired service, uses the load balancing algorithm to call one of the address. Caching of addresses locally help since making a network call to fetch the address each and every time impacts performance and is expensive too.
Each micro-service would leverage a component aka service client to talk to service-discovery. This is a part of the micro-service enabler family.
There are multiple tools available and here is a brief summary about those.
Consul, Eureka and Zookeeper
|What is it?||Consul is a service mesh solution providing a full featured control plane with service discovery, configuration, and segmentation functionality.||Eureka is a REST based service that is primarily used in the AWS cloud for locating services for the purpose of load balancing and failover of middle-tier servers.||Zookeeper is essentially a centralized service for distributed systems to a hierarchical key-value store, which is used to provide a distributed configuration service, synchronization service, and naming registry for large distributed systems.|
|Endpoint update||Always full content||Delta content with occasional full content|
|Polyglot support||Yes||Not out of the box.|
|HTTPS||Yes||Not out of the box.|
|Containarization||Built in Docker support||Not out of the box.|
The tool comparison though leans towards Consul, choice of service discovery tool should be made based on the specific needs.