Recently I've been pondering how to do service discovery.
Pretend you have a load balancer which accepts traffic and routes incoming requests to different back-ends. The loadbalancer might be pound, varnish, haproxy, nginx, or similar. The back-ends might be node applications, apache, or similar.
The typical configuration of the load-balancer will read:
# forward # backends backend web1 { .host = "10.0.0.4"; } backend web2 { .host = "10.0.0.6"; } backend web3 { .host = "10.0.0.5"; } # afterword
I've seen this same setup in many situations, and while it can easily be imagined that there might be "random HTTP servers" on your (V)LAN which shouldn't receive connections it seems like a pain to keep updating the backends.
Using UDP/multicast broadcasts it is trivial to announce "Hey I'm a HTTP-server with the name 'foo'", and it seems to me that this should allow seamless HTTP load-balancing.
To be more explicit - this is normal:
- The load-balancer listens for HTTP requests, and forwards them to back-ends.
- When back-ends go away they stop receiving traffic.
What I'd like to propose is another step:
- When a new back-end advertises itself with the tag "foo" it should be automatically added and start to receive traffic.
i.e. This allows backends to be removed from service when they go offline but also to be added when they come online. Without the load-balancer needing its configuration to be updated.
This means you'd not give a static list of back-ends to your load-balancer, instead you'd say "Route traffic to any service that adfvertises itself with the tag 'foo'.".
VLANS, firewalls, multicast, udp, all come into play, but in theory this strikes me as being useful, obvious, and simple.
(Failure cases? Well if the "announcer" dies then the backend won't get traffic routed to it. Just like if the backend were offline. And clearly if a backend is announced, but not receiving HTTP-requests it would be dropped as normal.)
If I get the time this evening I'll sit down and look at some load-balancer source code to see if any are written in such a way that I could add this "broadcast discovery" as a plugin/minor change.
Tags: discovery, http, load-balancing 14 comments
The way I've seen recently, is to use something like etcd1 to hold the location of your backends. The backend itself would register its location in etcd with a key that has a lifetime, and reregister on some sort of heartbeat. etcd can then be configured to call a script when a value is added or removed and update your haproxy configuration with the valid backends.
#matt
1: https://github.com/coreos/etcd