[Mongrel] Shared listening sockets
rob at robmela.com
Tue Oct 23 12:28:32 EDT 2007
Several years back I accidentally discovered that multiple processes can
listen on the same TCP/IP socket. The trick of course is that all the
processes are in the same process group, and the socket is opened by a
shared parent. The OS somehow was managing queuing up the various
calls to accept() on that socket. Since the watchdog parent / multiple
child servers is a common, this was a workable solution on the versions
of Linux we were using.
IIRC, the OS gracefully queued several processes' calls to accept(),
requiring no additional synchronization. But, even if that weren't the
case, there is still the option of puting an acceptor in a parent and
dispatching the client socket to available child servers.
The application I wrote has a watchdog process in C that opens up a
server socket before forking child server processes. The children get
passed the descriptor number for that server socket as an argument on
their command lines.
All child server processes then enter an accept loop. They all call
accept() on that same, shared descriptor . Each child, btw, opened up
its own "private" admin socket on a port that was an offset of the main,
shared service port ( and optionally on a different interface as well ).
Within a pool then processes are somewhat self-balancing -- a process
only calls accept() when it's got threads available and ready to handle
a reqeust. Clients, or a client load balancer, don't have to keep
track of traffic or request counts between individual server processes.
They also don't have to try back-end app servers individually before
finding a "thread" that's free -- if any process in a pool is
available, it's already sitting in accept() on that shared socket (
likely with others queued up behind it in their accept() calls).
If Mongrel's suitable as an Internet-facing front-end, then there might
be, for many applications, no need for a load balancing proxy. Simply
fire up a pool of mongrels at port 80, and they'll sort it all out among
themselves. Even for applications requiring multiple machines a scheme
like this would simplify load balancer proxy configurations (100
mongrels in a pool? No problem -- all one port!)
I'm sure the folks who wrote Mongrel thought of this and either tried it
or rejected it beforehand for good reason. And I had the luxury of
coding for just one platform. Perhaps others impose hurdles that make
this impractical. But even there, isn't there the Apache model of a
parent acceptor() passing client sockets to ready children?
-------------- next part --------------
A non-text attachment was scrubbed...
Size: 116 bytes
Desc: not available
Url : http://rubyforge.org/pipermail/mongrel-users/attachments/20071023/f7c43ca1/attachment.vcf
More information about the Mongrel-users