Norbert is a good example from a scalable production system. I general, it integrates Netty, Protocol Buffers and Zookeeper
into a lightweight framework for running clustered services. Protocol Buffers are used to specify your service API, Netty implements transport-layer abstractions and Zookeeper is essentially a fault-tolerant discovery service.
Every time a service instance is started Norbert registers it as available instance of a particular service type. From implementation perspective, it creates two Zookeeper trees:
- "/ServiceName/members" which lists all known instances of the service
- "/ServiceName/available" which lists currently available instances of the service
The most important property for each node is the url to use to connect to the corresponding service instance. It enables client-side load balancing - a Norbert client finds the list of urls for a given service name and attempt to connect to one of them is some order (e.g. round-robin or random).