mirror of
https://github.com/apache/httpd.git
synced 2025-08-08 15:02:10 +03:00
Display information about asynchronous connections in the server-status
PR: 44377 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1137360 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
3
CHANGES
3
CHANGES
@@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
Changes with Apache 2.3.13
|
Changes with Apache 2.3.13
|
||||||
|
|
||||||
|
*) mod_status: Display information about asynchronous connections in the
|
||||||
|
server-status. PR 44377. [Stefan Fritsch]
|
||||||
|
|
||||||
*) mpm_event: If the number of connections of a process is very high, or if
|
*) mpm_event: If the number of connections of a process is very high, or if
|
||||||
all workers are busy, don't accept new connections in that process.
|
all workers are busy, don't accept new connections in that process.
|
||||||
[Stefan Fritsch]
|
[Stefan Fritsch]
|
||||||
|
@@ -86,7 +86,8 @@
|
|||||||
|
|
||||||
module AP_MODULE_DECLARE_DATA status_module;
|
module AP_MODULE_DECLARE_DATA status_module;
|
||||||
|
|
||||||
static int server_limit, thread_limit, threads_per_child, max_servers;
|
static int server_limit, thread_limit, threads_per_child, max_servers,
|
||||||
|
is_async;
|
||||||
|
|
||||||
/* Implement 'ap_run_status_hook'. */
|
/* Implement 'ap_run_status_hook'. */
|
||||||
APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ap, STATUS, int, status_hook,
|
APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ap, STATUS, int, status_hook,
|
||||||
@@ -197,6 +198,8 @@ static int status_handler(request_rec *r)
|
|||||||
process_score *ps_record;
|
process_score *ps_record;
|
||||||
char *stat_buffer;
|
char *stat_buffer;
|
||||||
pid_t *pid_buffer, worker_pid;
|
pid_t *pid_buffer, worker_pid;
|
||||||
|
int *thread_idle_buffer = NULL;
|
||||||
|
int *thread_busy_buffer = NULL;
|
||||||
clock_t tu, ts, tcu, tcs;
|
clock_t tu, ts, tcu, tcs;
|
||||||
ap_generation_t mpm_generation, worker_generation;
|
ap_generation_t mpm_generation, worker_generation;
|
||||||
#ifdef HAVE_TIMES
|
#ifdef HAVE_TIMES
|
||||||
@@ -233,6 +236,10 @@ static int status_handler(request_rec *r)
|
|||||||
|
|
||||||
pid_buffer = apr_palloc(r->pool, server_limit * sizeof(pid_t));
|
pid_buffer = apr_palloc(r->pool, server_limit * sizeof(pid_t));
|
||||||
stat_buffer = apr_palloc(r->pool, server_limit * thread_limit * sizeof(char));
|
stat_buffer = apr_palloc(r->pool, server_limit * thread_limit * sizeof(char));
|
||||||
|
if (is_async) {
|
||||||
|
thread_idle_buffer = apr_palloc(r->pool, server_limit * sizeof(int));
|
||||||
|
thread_busy_buffer = apr_palloc(r->pool, server_limit * sizeof(int));
|
||||||
|
}
|
||||||
|
|
||||||
nowtime = apr_time_now();
|
nowtime = apr_time_now();
|
||||||
tu = ts = tcu = tcs = 0;
|
tu = ts = tcu = tcs = 0;
|
||||||
@@ -292,6 +299,10 @@ static int status_handler(request_rec *r)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
ps_record = ap_get_scoreboard_process(i);
|
ps_record = ap_get_scoreboard_process(i);
|
||||||
|
if (is_async) {
|
||||||
|
thread_idle_buffer[i] = 0;
|
||||||
|
thread_busy_buffer[i] = 0;
|
||||||
|
}
|
||||||
for (j = 0; j < thread_limit; ++j) {
|
for (j = 0; j < thread_limit; ++j) {
|
||||||
int indx = (i * thread_limit) + j;
|
int indx = (i * thread_limit) + j;
|
||||||
|
|
||||||
@@ -306,13 +317,23 @@ static int status_handler(request_rec *r)
|
|||||||
|
|
||||||
if (!ps_record->quiescing
|
if (!ps_record->quiescing
|
||||||
&& ps_record->pid) {
|
&& ps_record->pid) {
|
||||||
if (res == SERVER_READY
|
if (res == SERVER_READY) {
|
||||||
&& ps_record->generation == mpm_generation)
|
if (ps_record->generation == mpm_generation)
|
||||||
ready++;
|
ready++;
|
||||||
|
if (is_async)
|
||||||
|
thread_idle_buffer[i]++;
|
||||||
|
}
|
||||||
else if (res != SERVER_DEAD &&
|
else if (res != SERVER_DEAD &&
|
||||||
res != SERVER_STARTING &&
|
res != SERVER_STARTING &&
|
||||||
res != SERVER_IDLE_KILL)
|
res != SERVER_IDLE_KILL) {
|
||||||
busy++;
|
busy++;
|
||||||
|
if (is_async) {
|
||||||
|
if (res == SERVER_GRACEFUL)
|
||||||
|
thread_idle_buffer[i]++;
|
||||||
|
else
|
||||||
|
thread_busy_buffer[i]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* XXX what about the counters for quiescing/seg faulted
|
/* XXX what about the counters for quiescing/seg faulted
|
||||||
@@ -465,9 +486,69 @@ static int status_handler(request_rec *r)
|
|||||||
else
|
else
|
||||||
ap_rprintf(r, "BusyWorkers: %d\nIdleWorkers: %d\n", busy, ready);
|
ap_rprintf(r, "BusyWorkers: %d\nIdleWorkers: %d\n", busy, ready);
|
||||||
|
|
||||||
|
if (!short_report)
|
||||||
|
ap_rputs("</dl>", r);
|
||||||
|
|
||||||
|
if (is_async) {
|
||||||
|
int write_completion = 0, lingering_close = 0, keep_alive = 0,
|
||||||
|
connections = 0;
|
||||||
|
/*
|
||||||
|
* These differ from 'busy' and 'ready' in how gracefully finishing
|
||||||
|
* threads are counted. XXX: How to make this clear in the html?
|
||||||
|
*/
|
||||||
|
int busy_workers = 0, idle_workers = 0;
|
||||||
|
if (!short_report)
|
||||||
|
ap_rputs("\n\n<table rules=\"all\" cellpadding=\"1%\">\n"
|
||||||
|
"<tr><th rowspan=\"2\">PID</th>"
|
||||||
|
"<th colspan=\"2\">Connections</th>\n"
|
||||||
|
"<th colspan=\"2\">Threads</th>"
|
||||||
|
"<th colspan=\"4\">Async connections</th></tr>\n"
|
||||||
|
"<tr><th>total</th><th>accepting</th>"
|
||||||
|
"<th>busy</th><th>idle</th><th>writing</th>"
|
||||||
|
"<th>keep-alive</th><th>closing</th></tr>\n", r);
|
||||||
|
for (i = 0; i < server_limit; ++i) {
|
||||||
|
ps_record = ap_get_scoreboard_process(i);
|
||||||
|
if (ps_record->pid) {
|
||||||
|
connections += ps_record->connections;
|
||||||
|
write_completion += ps_record->write_completion;
|
||||||
|
keep_alive += ps_record->keep_alive;
|
||||||
|
lingering_close += ps_record->lingering_close;
|
||||||
|
busy_workers += thread_busy_buffer[i];
|
||||||
|
idle_workers += thread_idle_buffer[i];
|
||||||
|
if (!short_report)
|
||||||
|
ap_rprintf(r, "<tr><td>%" APR_PID_T_FMT "</td><td>%u</td>"
|
||||||
|
"<td>%s</td><td>%u</td><td>%u</td>"
|
||||||
|
"<td>%u</td><td>%u</td><td>%u</td>"
|
||||||
|
"</tr>\n",
|
||||||
|
ps_record->pid, ps_record->connections,
|
||||||
|
ps_record->not_accepting ? "no" : "yes",
|
||||||
|
thread_busy_buffer[i], thread_idle_buffer[i],
|
||||||
|
ps_record->write_completion,
|
||||||
|
ps_record->keep_alive,
|
||||||
|
ps_record->lingering_close);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!short_report) {
|
||||||
|
ap_rprintf(r, "<tr><td>Sum</td><td>%d</td><td> </td><td>%d</td>"
|
||||||
|
"<td>%d</td><td>%d</td><td>%d</td><td>%d</td>"
|
||||||
|
"</tr>\n</table>\n",
|
||||||
|
connections, busy_workers, idle_workers,
|
||||||
|
write_completion, keep_alive, lingering_close);
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ap_rprintf(r, "ConnsTotal: %d\n"
|
||||||
|
"ConnsAsyncWriting: %d\n"
|
||||||
|
"ConnsAsyncKeepAlive: %d\n"
|
||||||
|
"ConnsAsyncClosing: %d\n",
|
||||||
|
connections, write_completion, keep_alive,
|
||||||
|
lingering_close);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* send the scoreboard 'table' out */
|
/* send the scoreboard 'table' out */
|
||||||
if (!short_report)
|
if (!short_report)
|
||||||
ap_rputs("</dl><pre>", r);
|
ap_rputs("<pre>", r);
|
||||||
else
|
else
|
||||||
ap_rputs("Scoreboard: ", r);
|
ap_rputs("Scoreboard: ", r);
|
||||||
|
|
||||||
@@ -485,6 +566,7 @@ static int status_handler(request_rec *r)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (short_report)
|
if (short_report)
|
||||||
ap_rputs("\n", r);
|
ap_rputs("\n", r);
|
||||||
else {
|
else {
|
||||||
@@ -834,6 +916,7 @@ static int status_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp,
|
|||||||
if (threads_per_child == 0)
|
if (threads_per_child == 0)
|
||||||
threads_per_child = 1;
|
threads_per_child = 1;
|
||||||
ap_mpm_query(AP_MPMQ_MAX_DAEMONS, &max_servers);
|
ap_mpm_query(AP_MPMQ_MAX_DAEMONS, &max_servers);
|
||||||
|
ap_mpm_query(AP_MPMQ_IS_ASYNC, &is_async);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user