I have had an idea for replacing the perchild MPM boggling around inside
my head for awhile now. This is an idea for a different architecture to
allowing different UIDs to serve httpd requests. I am looking for all
feedback with my proposed approach.
First, we start with a concept I am calling 'Server Pools'. Each pool
has specific limits. These can include a maximum number of processes,
or other limits based on resource usage. A root server pool can contain
other pools, or sub pools.
(xxxx: perhaps 'server pools' is a bad word for this idea?)
Each sub pool could be set to specific User IDs.(ala perchild).
However, you could have 0 or 100 of them currently running at any one
time. Their spawning should be based on the same rules as normal httpd
processes. However, they must be able to go down to 0 alive processes.
This enables the realistic use of this MPM in a larger hosting
environment.
Since you need the ability to spawn more processes on demand when none
exist, there will be a 'controller process' that manages all server
pools, killing or using fork() to spawn new pools.
A frontend will parse the incoming request, and provide other services,
like input filters, output filters, and logging. This frontend will
pass the request back to a server pool by asking the control process for
which server pool should service this request. If no server pool
currently has any processes running, the control process will spawn one
or more.
I disagree with the concept of passing a client socket directly to the
back-end as perchild does. I believe it would be better to write a
protocol handler for AJP or another binary type protocol and therefore,
hopefully, faster for passing requests to a backend server pool via Unix
Daemon Sockets. By passing the socket directly to the backend, we enter
a hell related to input filters, keep alive requests, and http 1.1
pipelining. I also believe that for most cases, an optimized AJP like
protocol would be just as fast as directly writing to the client. (not
for static content, but for a PHP script..)
Some ASCII drawing of what this might look like:
[ Client ]
|
| (HTTP)
|
[ Frontend Process ]
| |
| (AJP) | (Find/Found Pool)
| |
| [ Control Process ]
| |
| | (Die, Spawn)
| |
[ Backend Server Pool ]
What this Solves:
- Keep Alive/Pipelining/SSL decoding.. etc. These are all handled by the
fontend.
- PHP Support. The backends could be process or threaded, it doesn't
matter, but at the same time, the frontend could resemble the Event or
Worker MPM.
Problems:
- Context Switching Sucks. This model has way too many for a single
request.
Thoughts:
- Hacking a demo via mod_proxy
- Is this a better design than perchild MPM?
- What are the other design considerations to doing 'perchild' the
'right' way?
In some ways, this is just a more automated mod_proxy w/ load balancing
that will auto-spawn your backend servers on demand. I believe it might
be best to write this whole MPM as a hybrid MPM and mod_proxy module.
I am pretty sure this whole idea is sketchy in parts. I just scratched
it all down at midnight. All comments are welcome.
-Paul Querna