Hello again!
I see that you have added a special case if MinProcessors is 0, then it
will allow processor count to be below MinSpareProcessors (if
IdleTimeout is reached).
This gets really bad, if one of the active workers hangs and all the
other workers get killed, because noone would accept new connections and
noone will clone new children.
The steps to reproduce this:
- use this peruser configuration:
<IfModule peruser.c>
ServerLimit 700
MaxClients 700
MinSpareProcessors 1
MaxSpareProcessors 20
MinProcessors 0
MaxProcessors 80
MaxRequestsPerChild 1000
ExpireTimeout 7200
IdleTimeout 10
MinMultiplexers 3
MaxMultiplexers 40
MultiplexerIdleTimeout 120
ProcessorWaitTimeout 5
</IfModule>
- create an infinite sleep script (for example in PHP: <?php while(true)
sleep(1); ?>)
- start the server and run lynx on this script (lynx
http://hostname/sleep.php). Lynx will start to wait for the response.
- if you look at the server-status or ps aux, you can see 2 workers (one
of them is handling the sleep script, and the second is idle).
- wait until idletimeout kicks in. There is now only the "sleeping"
worker left and the virtualhost is no longer accessible.
- run ab -c 100 -n 10000 against the dead virtualhost (you may need to
repeat it a couple of times as ab timeouts).
- the whole server is now not accessible, all multiplexers have been
spawned and are trying to forward the requests to the dead virtualhost's
workers but there is noone to accept them.
There would be 2 ways to fix this:
- rewrite the child cloning part and make multiplexers able to clone
other children
- disallow setting MinSpareProcessors to 0. If MinProcessors is 0 then
kill the idle workers only if there are no active workers and all the
workers have their idletimeout limit reached.
Cheers,
Taavi
_______________________________________________
Peruser mailing list
[email protected]
http://www.telana.com/mailman/listinfo/peruser