I've been thinking about using ZeroMQ for RPC, but the one problem it doesn't solve is discovery, ie. finding a peer to talk to among a dynamic pool over which you'd like to load-balance. zbeacon looks promising until I realized it uses UDP broadcasts.
You can do it with ZooKeeper or Consul, but then you have to roll that glue for every app, or write a library which only you are going to end up using, and you'll end up doing it for every language you implement in. We write a lot of microservices, in all sorts of languages, and we'd like to move away from a centralized load-balancer, which is both a bottleneck and a SPoF.
(gRPC looks like a great start, but I'm puzzled why they chose to ignore/defer discovery. Plain one-on-one RPC is trivial, the difficult part is making it completely distributed and fault-tolerant, neither of which gRPC seem to address at all.)
Discovery is one of those problems with dozens of answers that depend on your context. For many cases, UDP broadcast/multicast is perfect. For others, a broker can help a lot (ZeroMQ has a broker, called Malamute, that is easy to use for discovery). For other cases, you need a mix of stable and unstable pieces, and so CZMQ has a zgossip class that does this.
It's an emergent problem. One good pattern that's emerging are clusters of clusters; e.g. each box supports a cloud of small services that talk to each other and to a single broker on the box, and the brokers on a network then discover each other opportunistically with a mix of broadcasts, manual assistance, and gossip.
While you can solve problem of discovery by introducing your own broker, you will still have problems such as single POF etc. This is because ZMQ was designed for different purpose and you are trying to forcefully fit it to unrelated purpose.
There are many solutions to what you want to accomplish and each one has its fans. I personally like smartstack because it combines two very mature and battle tested technologies: Zookeeper and haproxy.
ZeroMQ sockets can connect or bind, and this is independent of the socket type. If you want to load balance requests against a dynamic number of responders, just have the responders connect their REP sockets to a set of bound REQ sockets.
ZeroMQ merely solves exposure of sockets as queues. In all distributed systems, there must be a set of known hosts, or discovery becomes tedious. DNS is an easy way to solve this.
ZeroMQ is an abstraction that hides a lot of complexity for you in the name of convenience, and there's no reason why it couldn't abstract discovery, too. Instead you have to build it from scratch for every client app.
You can do it with ZooKeeper or Consul, but then you have to roll that glue for every app, or write a library which only you are going to end up using, and you'll end up doing it for every language you implement in. We write a lot of microservices, in all sorts of languages, and we'd like to move away from a centralized load-balancer, which is both a bottleneck and a SPoF.
(gRPC looks like a great start, but I'm puzzled why they chose to ignore/defer discovery. Plain one-on-one RPC is trivial, the difficult part is making it completely distributed and fault-tolerant, neither of which gRPC seem to address at all.)