Hi, When some vhost's scripts exhaust all process slots available to it (FcgidMaxProcessesPerClass), next requests are waiting for over 60 seconds before issuing 503 error.
I came across this while modifying suexec to use cgroups to provide better resource separation for use in our shared hosting environment. When some vhost got it's cpu resources sharply reduced its incoming traffic quickly occupyed all available connection slots rendering whole web server unavailable. This could lead to a dos situation when unresponsive fcgi application will occupy large number of connection slots. mod_fcgid could use process statistics to detect these situations and return 503 error sooner. Maybe check for active and idle time, or allow only a limited number of clients to wait for a single fcgi process class if all of them are busy. http://svn.apache.org/repos/asf/httpd/mod_fcgid/trunk/modules/fcgid/fcgid_bridge.c #define FCGID_REQUEST_COUNT 32 #define FCGID_APPLY_TRY_COUNT 2 handle_request(request_rec * r, int role, fcgid_cmd_conf *cmd_conf, apr_bucket_brigade * output_brigade) { ... /* Try to get a connected ipc handle */ for (i = 0; i < FCGID_REQUEST_COUNT; i++) { /* Apply a free process slot, send a spawn request if I can't get one */ for (j = 0; j < FCGID_APPLY_TRY_COUNT; j++) { /* Init spawn request */ procmgr_init_spawn_cmd(&fcgi_request, r, cmd_conf); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ do we have to do it on every iteration ? if yes I think it can be moved just before procmgr_post_spawn_cmd(&fcgi_request, r); so if there is a free procnode we don't call procmgr_init_spawn_cmd at all bucket_ctx->ipc.connect_timeout = fcgi_request.cmdopts.ipc_connect_timeout; bucket_ctx->ipc.communation_timeout = fcgi_request.cmdopts.ipc_comm_timeout; /* Apply a process slot */ bucket_ctx->procnode = apply_free_procnode(r, &fcgi_request); if (bucket_ctx->procnode) break; /* Avoid sleeping the very first time through if there are no busy processes; the problem is just that we haven't spawned anything yet, so waiting is pointless */ if (i > 0 || j > 0 || count_busy_processes(r, &fcgi_request)) { apr_sleep(apr_time_from_sec(1)); bucket_ctx->procnode = apply_free_procnode(r, &fcgi_request); if (bucket_ctx->procnode) break; } /* Send a spawn request if I can't get a process slot */ procmgr_post_spawn_cmd(&fcgi_request, r); } -- Michal Grzedzicki