I am trying to understand the advantages of service discovery compared to load-balancing within the context of a microservice mesh where many instances/nodes/VMs/containers of many web services are all calling each other in a complicated web-pattern. And my understanding of the situation is this:
- Service discovery -- when implemented properly -- keeps each instance of each service aware of all the valid IPs/addresses of all the services it cares about
- Each service can then employ its own client-side load-balancing to determine which instances of which services it makes a request to
- Traditional service-level load-balancers have the problem where an instance sitting behind them becomes unhealthy or goes offline, and they continue serving traffic to it
Hence let's say we have Microservice A and B, and A needs to make requests to B. In a traditional load balanced setting, A and B would be behind their own load balancers respectively, say, https://a.example.com
and https://b.example.com
. When any instance of A need to make a request to B, it has https://b.example.com
in its configs as the host to make contact with, and the load balancer there will farm the request out to whatever healthy nodes sit behind it.
The problem here, again, is that a B instance might have gone offline since the last health check to it (from the B balancer) and now that B balancer unknowingly sends a request off to it.
Also, the load balancer still needs to know which instances to route traffic to, which is a configuration that typically needs to be done manually. The solution to this, in my mind, is have automated registration/de-registration of instances with their load balancer.
So properly-implemented service discovery swoops in and takes care of this scenario. The service discovery tool (Consul, etc.) is constantly pinging each instance of both service A and B and letting each instance of A know the hosts/IPs/etc. of each healthy instance of B. But now its up to A to come up with its own client-side balancing solution for which healthy instance of B it connects to.
So to begin with, if anything I've said above is incorrect or misled, please begin by correcting me! Assuming I'm more or less understanding the lay of the land here, I'll move on to my question:
My question
To me, this just seems like a timing issue with balancer health checks. If the balancer can be written/configured to check the health of the instances sitting behind it just as regularly as the service discovery (Consul, etc.) tool would, and if the instances are always registering themselves with their load balancer at startup time, then the balancer will have the same information available to it as you would have in a service discovery paradigm. No?
Quasi-believable, pseudo-real world example to work with
- Say I have an Order Service (
orderws
) that has a "order item" endpoint exposed at, say,POST /v1/orders
- Let's say all the
orderws
nodes are sitting behind a load balancer athttps://orderws.example.com
- Say this
orderws
calls 2 other web services:- a Payment WS to make payments and transfer money,
paymentws
exposing aPOST /v1/payments
endpoint with all nodes behind load balancer athttps://payments.example.com
; and - a Shipping WS (
shippingws
) that, upon successful payment of an order, results with the ordered item being taken off the shelf at a warehouse and shipping to the customer; the Orders WS callsPOST /v1/shipment
endpoint with all Shipping WS nodes behindhttps://shippingws.example.com
- a Payment WS to make payments and transfer money,
- Now then, how would service discovery and load balancing compliment each other here? Ideally, if even 1 Payment or Shipping node exists, their load balancer will serve traffic from the load balanced URLs. If no nodes exist behind a balancer, then what would happen (service discovery-wise, between Order WS instances and the Service Registry) with Order WS nodes attempting to handle order requests?