Skip to content

Commit ace0117

Browse files
committed
sapi/fpm: fixed fpm status inconsistent issue when using fastcgi_finish_request with keepalive connection
Added new field to represent the number of keepalive connections in fpm status page. @see php#19191
1 parent 96c0bc5 commit ace0117

File tree

6 files changed

+72
-5
lines changed

6 files changed

+72
-5
lines changed

sapi/fpm/fpm/fpm_process_ctl.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@ static void fpm_pctl_perform_idle_server_maintenance(struct timeval *now) /* {{{
333333
struct fpm_child_s *last_idle_child = NULL;
334334
int idle = 0;
335335
int active = 0;
336+
int reused = 0;
336337
int children_to_fork;
337338
unsigned cur_lq = 0;
338339

@@ -359,7 +360,8 @@ static void fpm_pctl_perform_idle_server_maintenance(struct timeval *now) /* {{{
359360
fpm_scoreboard_update_begin(wp->scoreboard);
360361

361362
for (child = wp->children; child; child = child->next) {
362-
if (fpm_request_is_idle(child)) {
363+
int reuse_cnt = 0;
364+
if (fpm_request_is_idle_with_reuse_count(child, &reuse_cnt)) {
363365
if (last_idle_child == NULL) {
364366
last_idle_child = child;
365367
} else {
@@ -370,10 +372,13 @@ static void fpm_pctl_perform_idle_server_maintenance(struct timeval *now) /* {{{
370372
idle++;
371373
} else {
372374
active++;
375+
if (reuse_cnt > 0) {
376+
reused--;
377+
}
373378
}
374379
}
375380

376-
fpm_scoreboard_update_commit(idle, active, cur_lq, -1, -1, -1, 0, FPM_SCOREBOARD_ACTION_SET, wp->scoreboard);
381+
fpm_scoreboard_update_commit(idle, active, cur_lq, -1, -1, -1, reused, FPM_SCOREBOARD_ACTION_SET, wp->scoreboard);
377382

378383
/* this is specific to PM_STYLE_ONDEMAND */
379384
if (wp->config->pm == PM_STYLE_ONDEMAND) {

sapi/fpm/fpm/fpm_request.c

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ void fpm_request_reading_headers(void)
6363
struct fpm_scoreboard_proc_s *proc;
6464

6565
struct timeval now;
66+
int reused_times = 0;
6667
clock_t now_epoch;
6768
#ifdef HAVE_TIMES
6869
struct tms cpu;
@@ -96,10 +97,19 @@ void fpm_request_reading_headers(void)
9697
proc->query_string[0] = '\0';
9798
proc->auth_user[0] = '\0';
9899
proc->content_length = 0;
100+
// @note reuse this field as keepalive connection reuse counter.
101+
// 000
102+
reused_times = (proc->used += 8) >> 3;
99103
fpm_scoreboard_proc_release(proc);
100104

101-
/* idle--, active++, request++ */
102-
fpm_scoreboard_update_commit(-1, 1, 0, 0, 1, 0, 0, FPM_SCOREBOARD_ACTION_INC, NULL);
105+
// means this is used for multiple times
106+
if (reused_times > 1) {
107+
/* request++, lq_len if reused_times == 2 */
108+
fpm_scoreboard_update_commit(0, 0, 0, reused_times == 2 ? 1 : 0, 1, 0, 0, FPM_SCOREBOARD_ACTION_INC, NULL);
109+
} else {
110+
/* idle--, active++, request++ */
111+
fpm_scoreboard_update_commit(-1, 1, 0, 0, 1, 0, 0, FPM_SCOREBOARD_ACTION_INC, NULL);
112+
}
103113
}
104114

105115
void fpm_request_info(void)
@@ -206,6 +216,7 @@ void fpm_request_finished(void)
206216
{
207217
struct fpm_scoreboard_proc_s *proc;
208218
struct timeval now;
219+
int reused_times;
209220

210221
fpm_clock_get(&now);
211222

@@ -214,10 +225,18 @@ void fpm_request_finished(void)
214225
zlog(ZLOG_WARNING, "failed to acquire proc scoreboard");
215226
return;
216227
}
217-
228+
reused_times = (proc->used += 8) >> 3;
229+
// @note reuse this field as keepalive connection reuse counter, when this function got called, the connection is already closed, so we reset the counter.
230+
if (reused_times > 0) {
231+
proc->used = proc->used & 0x01;
232+
}
218233
proc->request_stage = FPM_REQUEST_FINISHED;
219234
proc->tv = now;
220235
fpm_scoreboard_proc_release(proc);
236+
if (reused_times > 1) {
237+
/* reused--, via lq_len if reused_times > 1 */
238+
fpm_scoreboard_update_commit(0, 0, 0, -1, 0, 0, 0, FPM_SCOREBOARD_ACTION_INC, NULL);
239+
}
221240
}
222241

223242
void fpm_request_check_timed_out(struct fpm_child_s *child, struct timeval *now, int terminate_timeout, int slowlog_timeout, int track_finished) /* {{{ */
@@ -293,6 +312,20 @@ int fpm_request_is_idle(struct fpm_child_s *child) /* {{{ */
293312
}
294313
/* }}} */
295314

315+
int fpm_request_is_idle_with_reuse_count(struct fpm_child_s *child, int *reuse_cnt) /* {{{ */
316+
{
317+
struct fpm_scoreboard_proc_s *proc;
318+
319+
/* no need in atomicity here */
320+
proc = fpm_scoreboard_proc_get_from_child(child);
321+
if (!proc) {
322+
return 0;
323+
}
324+
*reuse_cnt = proc->used >> 3;
325+
return proc->request_stage == FPM_REQUEST_ACCEPTING;
326+
}
327+
/* }}} */
328+
296329
int fpm_request_last_activity(struct fpm_child_s *child, struct timeval *tv) /* {{{ */
297330
{
298331
struct fpm_scoreboard_proc_s *proc;

sapi/fpm/fpm/fpm_request.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ struct timeval;
2121

2222
void fpm_request_check_timed_out(struct fpm_child_s *child, struct timeval *tv, int terminate_timeout, int slowlog_timeout, int track_finished);
2323
int fpm_request_is_idle(struct fpm_child_s *child);
24+
int fpm_request_is_idle_with_reuse_count(struct fpm_child_s *child, int *reuse_cnt);
2425
const char *fpm_request_get_stage_name(int stage);
2526
int fpm_request_last_activity(struct fpm_child_s *child, struct timeval *tv);
2627

sapi/fpm/fpm/fpm_scoreboard.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,9 @@ void fpm_scoreboard_update_commit(
175175
}
176176
if (slow_rq > 0) {
177177
scoreboard->slow_rq = slow_rq;
178+
} else if (slow_rq < 0) {
179+
// we reuse this as a reused connections counter.
180+
scoreboard->reused = -slow_rq;
178181
}
179182
} else {
180183
if (scoreboard->idle + idle > 0) {
@@ -183,6 +186,15 @@ void fpm_scoreboard_update_commit(
183186
scoreboard->idle = 0;
184187
}
185188

189+
// we use this to record the currently keepalive/reused connections.
190+
if (lq_len != 0) {
191+
if (scoreboard->reused + lq_len > 0) {
192+
scoreboard->reused += lq_len;
193+
} else {
194+
scoreboard->reused = 0;
195+
}
196+
}
197+
186198
if (scoreboard->active + active > 0) {
187199
scoreboard->active += active;
188200
} else {

sapi/fpm/fpm/fpm_scoreboard.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ struct fpm_scoreboard_s {
6161
time_t start_epoch;
6262
int idle;
6363
int active;
64+
int reused;
6465
int active_max;
6566
unsigned long int requests;
6667
unsigned int max_children_reached;

sapi/fpm/fpm/fpm_status.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ int fpm_status_handle_request(void) /* {{{ */
243243
"<tr><th>listen queue len</th><td>%u</td></tr>\n"
244244
"<tr><th>idle processes</th><td>%d</td></tr>\n"
245245
"<tr><th>active processes</th><td>%d</td></tr>\n"
246+
"<tr><th>reused processes</th><td>%d</td></tr>\n"
246247
"<tr><th>total processes</th><td>%d</td></tr>\n"
247248
"<tr><th>max active processes</th><td>%d</td></tr>\n"
248249
"<tr><th>max children reached</th><td>%u</td></tr>\n"
@@ -260,6 +261,7 @@ int fpm_status_handle_request(void) /* {{{ */
260261
"<th>start time</th>"
261262
"<th>start since</th>"
262263
"<th>requests</th>"
264+
"<th>rused</th>"
263265
"<th>request duration</th>"
264266
"<th>request method</th>"
265267
"<th>request uri</th>"
@@ -278,6 +280,7 @@ int fpm_status_handle_request(void) /* {{{ */
278280
"<td>%lu</td>"
279281
"<td>%lu</td>"
280282
"<td>%lu</td>"
283+
"<td>%lu</td>"
281284
"<td>%s</td>"
282285
"<td>%s%s%s</td>"
283286
"<td>%zu</td>"
@@ -309,6 +312,7 @@ int fpm_status_handle_request(void) /* {{{ */
309312
"<listen-queue-len>%u</listen-queue-len>\n"
310313
"<idle-processes>%d</idle-processes>\n"
311314
"<active-processes>%d</active-processes>\n"
315+
"<reused-processes>%d</reused-processes>\n"
312316
"<total-processes>%d</total-processes>\n"
313317
"<max-active-processes>%d</max-active-processes>\n"
314318
"<max-children-reached>%u</max-children-reached>\n"
@@ -325,6 +329,7 @@ int fpm_status_handle_request(void) /* {{{ */
325329
"<start-time>%s</start-time>"
326330
"<start-since>%lu</start-since>"
327331
"<requests>%lu</requests>"
332+
"<reused>%lu</reused>"
328333
"<request-duration>%lu</request-duration>"
329334
"<request-method>%s</request-method>"
330335
"<request-uri>%s%s%s</request-uri>"
@@ -357,6 +362,7 @@ int fpm_status_handle_request(void) /* {{{ */
357362
"\"listen queue len\":%u,"
358363
"\"idle processes\":%d,"
359364
"\"active processes\":%d,"
365+
"\"reused processes\":%d,"
360366
"\"total processes\":%d,"
361367
"\"max active processes\":%d,"
362368
"\"max children reached\":%u,"
@@ -374,6 +380,7 @@ int fpm_status_handle_request(void) /* {{{ */
374380
"\"start time\":%s,"
375381
"\"start since\":%lu,"
376382
"\"requests\":%lu,"
383+
"\"reused\":%lu,"
377384
"\"request duration\":%lu,"
378385
"\"request method\":\"%s\","
379386
"\"request uri\":\"%s%s%s\","
@@ -417,6 +424,9 @@ int fpm_status_handle_request(void) /* {{{ */
417424
"# HELP phpfpm_active_processes The number of active processes.\n"
418425
"# TYPE phpfpm_active_processes gauge\n"
419426
"phpfpm_active_processes %d\n"
427+
"# HELP phpfpm_reused_active_processes The number of reused active processes.\n"
428+
"# TYPE phpfpm_reused_active_processes gauge\n"
429+
"phpfpm_reused_active_processes %d\n"
420430
"# HELP phpfpm_total_processes The number of idle + active processes.\n"
421431
"# TYPE phpfpm_total_processes gauge\n"
422432
"phpfpm_total_processes %d\n"
@@ -457,6 +467,7 @@ int fpm_status_handle_request(void) /* {{{ */
457467
"listen queue len: %u\n"
458468
"idle processes: %d\n"
459469
"active processes: %d\n"
470+
"reused processes: %d\n"
460471
"total processes: %d\n"
461472
"max active processes: %d\n"
462473
"max children reached: %u\n"
@@ -471,6 +482,7 @@ int fpm_status_handle_request(void) /* {{{ */
471482
"start time: %s\n"
472483
"start since: %lu\n"
473484
"requests: %lu\n"
485+
"reused: %lu\n"
474486
"request duration: %lu\n"
475487
"request method: %s\n"
476488
"request URI: %s%s%s\n"
@@ -496,6 +508,7 @@ int fpm_status_handle_request(void) /* {{{ */
496508
scoreboard_p->lq_len,
497509
scoreboard_p->idle,
498510
scoreboard_p->active,
511+
scoreboard_p->reused,
499512
scoreboard_p->idle + scoreboard_p->active,
500513
scoreboard_p->active_max,
501514
scoreboard_p->max_children_reached,
@@ -511,6 +524,7 @@ int fpm_status_handle_request(void) /* {{{ */
511524
scoreboard_p->lq_len,
512525
scoreboard_p->idle,
513526
scoreboard_p->active,
527+
scoreboard_p->reused,
514528
scoreboard_p->idle + scoreboard_p->active,
515529
scoreboard_p->active_max,
516530
scoreboard_p->max_children_reached,
@@ -598,6 +612,7 @@ int fpm_status_handle_request(void) /* {{{ */
598612
time_buffer,
599613
(unsigned long) (now_epoch - proc->start_epoch),
600614
proc->requests,
615+
proc->used >> 3,
601616
(unsigned long) (duration.tv_sec * 1000000UL + duration.tv_usec),
602617
proc->request_method[0] != '\0' ? proc->request_method : "-",
603618
proc->request_uri[0] != '\0' ? proc->request_uri : "-",

0 commit comments

Comments
 (0)