mirror of
https://github.com/php/php-src.git
synced 2025-08-21 01:45:16 +02:00
- add "listen queue len" stat (thx to Andrei Nigmatulin)
This commit is contained in:
parent
584ddb0c6e
commit
b38d57249e
9 changed files with 180 additions and 10 deletions
|
@ -516,6 +516,39 @@ AC_DEFUN([AC_FPM_BUILTIN_ATOMIC],
|
||||||
AC_MSG_RESULT([no])
|
AC_MSG_RESULT([no])
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([AC_FPM_LQ],
|
||||||
|
[
|
||||||
|
have_lq=no
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([for TCP_INFO])
|
||||||
|
|
||||||
|
AC_TRY_COMPILE([ #include <netinet/tcp.h> ], [struct tcp_info ti; int x = TCP_INFO;], [
|
||||||
|
have_lq=tcp_info
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
], [
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
])
|
||||||
|
|
||||||
|
if test "$have_lq" = "tcp_info"; then
|
||||||
|
AC_DEFINE([HAVE_LQ_TCP_INFO], 1, [do we have TCP_INFO?])
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$have_lq" = "no" ; then
|
||||||
|
AC_MSG_CHECKING([for SO_LISTENQLEN])
|
||||||
|
|
||||||
|
AC_TRY_COMPILE([ #include <sys/socket.h> ], [int x = SO_LISTENQLIMIT; int y = SO_LISTENQLEN;], [
|
||||||
|
have_lq=so_listenq
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
], [
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
])
|
||||||
|
|
||||||
|
if test "$have_lq" = "tcp_info"; then
|
||||||
|
AC_DEFINE([HAVE_LQ_SO_LISTENQ], 1, [do we have SO_LISTENQxxx?])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
])
|
||||||
dnl }}}
|
dnl }}}
|
||||||
|
|
||||||
AC_MSG_CHECKING(for FPM build)
|
AC_MSG_CHECKING(for FPM build)
|
||||||
|
@ -543,6 +576,7 @@ if test "$PHP_FPM" != "no"; then
|
||||||
AC_FPM_CLOCK
|
AC_FPM_CLOCK
|
||||||
AC_FPM_TRACE
|
AC_FPM_TRACE
|
||||||
AC_FPM_BUILTIN_ATOMIC
|
AC_FPM_BUILTIN_ATOMIC
|
||||||
|
AC_FPM_LQ
|
||||||
|
|
||||||
PHP_ARG_WITH(fpm-user,,
|
PHP_ARG_WITH(fpm-user,,
|
||||||
[ --with-fpm-user[=USER] Set the user for php-fpm to run as. (default: nobody)], nobody, no)
|
[ --with-fpm-user[=USER] Set the user for php-fpm to run as. (default: nobody)], nobody, no)
|
||||||
|
|
|
@ -576,7 +576,7 @@ static int fpm_conf_process_all_pools() /* {{{ */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
fpm_status_update_accepted_conn(wp->shm_status, 0);
|
fpm_status_update_accepted_conn(wp->shm_status, 0);
|
||||||
fpm_status_update_activity(wp->shm_status, -1, -1, -1, 1);
|
fpm_status_update_activity(wp->shm_status, -1, -1, -1, 0, -1, 1);
|
||||||
fpm_status_update_max_children_reached(wp->shm_status, 0);
|
fpm_status_update_max_children_reached(wp->shm_status, 0);
|
||||||
fpm_status_set_pm(wp->shm_status, wp->config->pm);
|
fpm_status_set_pm(wp->shm_status, wp->config->pm);
|
||||||
/* memset(&fpm_status.last_update, 0, sizeof(fpm_status.last_update)); */
|
/* memset(&fpm_status.last_update, 0, sizeof(fpm_status.last_update)); */
|
||||||
|
|
|
@ -42,3 +42,9 @@
|
||||||
#define HAVE_FPM_TRACE 0
|
#define HAVE_FPM_TRACE 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_LQ_TCP_INFO) || defined(HAVE_LQ_SO_LISTENQ)
|
||||||
|
#define HAVE_FPM_LQ 1
|
||||||
|
#else
|
||||||
|
#define HAVE_FPM_LQ 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "fpm_request.h"
|
#include "fpm_request.h"
|
||||||
#include "fpm_worker_pool.h"
|
#include "fpm_worker_pool.h"
|
||||||
#include "fpm_status.h"
|
#include "fpm_status.h"
|
||||||
|
#include "fpm_sockets.h"
|
||||||
#include "zlog.h"
|
#include "zlog.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -327,6 +328,7 @@ static void fpm_pctl_perform_idle_server_maintenance(struct timeval *now, struct
|
||||||
int idle = 0;
|
int idle = 0;
|
||||||
int active = 0;
|
int active = 0;
|
||||||
int children_to_fork;
|
int children_to_fork;
|
||||||
|
unsigned cur_lq;
|
||||||
|
|
||||||
if (wp->config == NULL) continue;
|
if (wp->config == NULL) continue;
|
||||||
|
|
||||||
|
@ -352,7 +354,10 @@ static void fpm_pctl_perform_idle_server_maintenance(struct timeval *now, struct
|
||||||
}
|
}
|
||||||
|
|
||||||
/* update status structure for all PMs */
|
/* update status structure for all PMs */
|
||||||
fpm_status_update_activity(wp->shm_status, idle, active, idle + active, 0);
|
if (0 > fpm_socket_get_listening_queue(wp, &cur_lq, NULL)) {
|
||||||
|
cur_lq = 0;
|
||||||
|
}
|
||||||
|
fpm_status_update_activity(wp->shm_status, idle, active, idle + active, cur_lq, wp->listening_queue_len, 0);
|
||||||
|
|
||||||
/* the rest is only used by PM_STYLE_DYNAMIC */
|
/* the rest is only used by PM_STYLE_DYNAMIC */
|
||||||
if (wp->config->pm != PM_STYLE_DYNAMIC) continue;
|
if (wp->config->pm != PM_STYLE_DYNAMIC) continue;
|
||||||
|
|
|
@ -344,6 +344,10 @@ int fpm_sockets_init_main() /* {{{ */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (0 > fpm_socket_get_listening_queue(wp, NULL, (unsigned *) &wp->listening_queue_len)) {
|
||||||
|
wp->listening_queue_len = -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (wp->listening_socket == -1) {
|
if (wp->listening_socket == -1) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -373,3 +377,76 @@ int fpm_sockets_init_main() /* {{{ */
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
#if HAVE_FPM_LQ
|
||||||
|
|
||||||
|
#ifdef HAVE_LQ_TCP_INFO
|
||||||
|
|
||||||
|
#include <netinet/tcp.h>
|
||||||
|
|
||||||
|
int fpm_socket_get_listening_queue(struct fpm_worker_pool_s *wp, unsigned *cur_lq, unsigned *max_lq)
|
||||||
|
{
|
||||||
|
if (wp->listen_address_domain != FPM_AF_INET) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct tcp_info info;
|
||||||
|
socklen_t len = sizeof(info);
|
||||||
|
|
||||||
|
if (0 > getsockopt(wp->listening_socket, IPPROTO_TCP, TCP_INFO, &info, &len)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* kernel >= 2.6.24 return non-zero here, that means operation is supported */
|
||||||
|
if (info.tcpi_sacked == 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cur_lq) {
|
||||||
|
*cur_lq = info.tcpi_unacked;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (max_lq) {
|
||||||
|
*max_lq = info.tcpi_sacked;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_LQ_SO_LISTENQ
|
||||||
|
|
||||||
|
int fpm_socket_get_listening_queue(struct fpm_worker_pool_s *wp, unsigned *cur_lq, unsigned *max_lq)
|
||||||
|
{
|
||||||
|
int val;
|
||||||
|
socklen_t len = sizeof(val);
|
||||||
|
|
||||||
|
if (cur_lq) {
|
||||||
|
if (0 > getsockopt(wp->listening_socket, SOL_SOCKET, SO_LISTENQLEN, &val, &len)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*cur_lq = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (max_lq) {
|
||||||
|
if (0 > getsockopt(wp->listening_socket, SOL_SOCKET, SO_LISTENQLIMIT, &val, &len)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*max_lq = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
int fpm_socket_get_listening_queue(struct fpm_worker_pool_s *wp, unsigned *cur_lq, unsigned *max_lq)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
enum fpm_address_domain fpm_sockets_domain_from_address(char *addr);
|
enum fpm_address_domain fpm_sockets_domain_from_address(char *addr);
|
||||||
int fpm_sockets_init_main();
|
int fpm_sockets_init_main();
|
||||||
|
int fpm_socket_get_listening_queue(struct fpm_worker_pool_s *wp, unsigned *cur_lq, unsigned *max_lq);
|
||||||
|
|
||||||
|
|
||||||
static inline int fd_set_blocked(int fd, int blocked) /* {{{ */
|
static inline int fd_set_blocked(int fd, int blocked) /* {{{ */
|
||||||
|
|
|
@ -133,7 +133,7 @@ void fpm_status_update_max_children_reached(struct fpm_shm_s *shm, unsigned int
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
void fpm_status_update_activity(struct fpm_shm_s *shm, int idle, int active, int total, int clear_last_update) /* {{{ */
|
void fpm_status_update_activity(struct fpm_shm_s *shm, int idle, int active, int total, unsigned cur_lq, int max_lq, int clear_last_update) /* {{{ */
|
||||||
{
|
{
|
||||||
struct fpm_status_s status;
|
struct fpm_status_s status;
|
||||||
|
|
||||||
|
@ -146,6 +146,8 @@ void fpm_status_update_activity(struct fpm_shm_s *shm, int idle, int active, int
|
||||||
status.idle = idle;
|
status.idle = idle;
|
||||||
status.active = active;
|
status.active = active;
|
||||||
status.total = total;
|
status.total = total;
|
||||||
|
status.cur_lq = cur_lq;
|
||||||
|
status.max_lq = max_lq;
|
||||||
if (clear_last_update) {
|
if (clear_last_update) {
|
||||||
memset(&status.last_update, 0, sizeof(status.last_update));
|
memset(&status.last_update, 0, sizeof(status.last_update));
|
||||||
} else {
|
} else {
|
||||||
|
@ -164,14 +166,28 @@ static void fpm_status_handle_status_txt(struct fpm_status_s *status, char **out
|
||||||
}
|
}
|
||||||
|
|
||||||
spprintf(output, 0,
|
spprintf(output, 0,
|
||||||
"accepted conn: %lu\n"
|
|
||||||
"pool: %s\n"
|
"pool: %s\n"
|
||||||
"process manager: %s\n"
|
"process manager: %s\n"
|
||||||
|
"accepted conn: %lu\n"
|
||||||
|
#if HAVE_FPM_LQ
|
||||||
|
"listen queue len: %u\n"
|
||||||
|
"max listen queue len: %d\n"
|
||||||
|
#endif
|
||||||
"idle processes: %d\n"
|
"idle processes: %d\n"
|
||||||
"active processes: %d\n"
|
"active processes: %d\n"
|
||||||
"total processes: %d\n"
|
"total processes: %d\n"
|
||||||
"max children reached: %u\n",
|
"max children reached: %u\n",
|
||||||
status->accepted_conn, fpm_status_pool, status->pm == PM_STYLE_STATIC ? "static" : "dynamic", status->idle, status->active, status->total, status->max_children_reached);
|
fpm_status_pool,
|
||||||
|
status->pm == PM_STYLE_STATIC ? "static" : "dynamic",
|
||||||
|
status->accepted_conn,
|
||||||
|
#if HAVE_FPM_LQ
|
||||||
|
status->cur_lq,
|
||||||
|
status->max_lq,
|
||||||
|
#endif
|
||||||
|
status->idle,
|
||||||
|
status->active,
|
||||||
|
status->total,
|
||||||
|
status->max_children_reached);
|
||||||
|
|
||||||
spprintf(content_type, 0, "Content-Type: text/plain");
|
spprintf(content_type, 0, "Content-Type: text/plain");
|
||||||
}
|
}
|
||||||
|
@ -185,15 +201,29 @@ static void fpm_status_handle_status_html(struct fpm_status_s *status, char **ou
|
||||||
|
|
||||||
spprintf(output, 0,
|
spprintf(output, 0,
|
||||||
"<table>\n"
|
"<table>\n"
|
||||||
"<tr><th>accepted conn</th><td>%lu</td></tr>\n"
|
|
||||||
"<tr><th>pool</th><td>%s</td></tr>\n"
|
"<tr><th>pool</th><td>%s</td></tr>\n"
|
||||||
"<tr><th>process manager</th><td>%s</td></tr>\n"
|
"<tr><th>process manager</th><td>%s</td></tr>\n"
|
||||||
|
"<tr><th>accepted conn</th><td>%lu</td></tr>\n"
|
||||||
|
#if HAVE_FPM_LQ
|
||||||
|
"<tr><th>listen queue len</th><td>%u</td></tr>\n"
|
||||||
|
"<tr><th>max listen queue len</th><td>%d</td></tr>\n"
|
||||||
|
#endif
|
||||||
"<tr><th>idle processes</th><td>%d</td></tr>\n"
|
"<tr><th>idle processes</th><td>%d</td></tr>\n"
|
||||||
"<tr><th>active processes</th><td>%d</td></tr>\n"
|
"<tr><th>active processes</th><td>%d</td></tr>\n"
|
||||||
"<tr><th>total processes</th><td>%d</td></tr>\n"
|
"<tr><th>total processes</th><td>%d</td></tr>\n"
|
||||||
"<tr><th>max children reached</th><td>%u</td></tr>\n"
|
"<tr><th>max children reached</th><td>%u</td></tr>\n"
|
||||||
"</table>",
|
"</table>",
|
||||||
status->accepted_conn, fpm_status_pool, status->pm == PM_STYLE_STATIC ? "static" : "dynamic", status->idle, status->active, status->total, status->max_children_reached);
|
fpm_status_pool,
|
||||||
|
status->pm == PM_STYLE_STATIC ? "static" : "dynamic",
|
||||||
|
status->accepted_conn,
|
||||||
|
#if HAVE_FPM_LQ
|
||||||
|
status->cur_lq,
|
||||||
|
status->max_lq,
|
||||||
|
#endif
|
||||||
|
status->idle,
|
||||||
|
status->active,
|
||||||
|
status->total,
|
||||||
|
status->max_children_reached);
|
||||||
|
|
||||||
spprintf(content_type, 0, "Content-Type: text/html");
|
spprintf(content_type, 0, "Content-Type: text/html");
|
||||||
}
|
}
|
||||||
|
@ -207,15 +237,29 @@ static void fpm_status_handle_status_json(struct fpm_status_s *status, char **ou
|
||||||
|
|
||||||
spprintf(output, 0,
|
spprintf(output, 0,
|
||||||
"{"
|
"{"
|
||||||
"\"accepted conn\":%lu,"
|
|
||||||
"\"pool\":\"%s\","
|
"\"pool\":\"%s\","
|
||||||
"\"process manager\":\"%s\","
|
"\"process manager\":\"%s\","
|
||||||
|
"\"accepted conn\":%lu,"
|
||||||
|
#if HAVE_FPM_LQ
|
||||||
|
"\"listen queue len\":%u,"
|
||||||
|
"\"max listen queue len\":%d,"
|
||||||
|
#endif
|
||||||
"\"idle processes\":%d,"
|
"\"idle processes\":%d,"
|
||||||
"\"active processes\":%d,"
|
"\"active processes\":%d,"
|
||||||
"\"total processes\":%d,"
|
"\"total processes\":%d,"
|
||||||
"\"max children reached\":%u"
|
"\"max children reached\":%u"
|
||||||
"}",
|
"}",
|
||||||
status->accepted_conn, fpm_status_pool, status->pm == PM_STYLE_STATIC ? "static" : "dynamic", status->idle, status->active, status->total, status->max_children_reached);
|
fpm_status_pool,
|
||||||
|
status->pm == PM_STYLE_STATIC ? "static" : "dynamic",
|
||||||
|
status->accepted_conn,
|
||||||
|
#if HAVE_FPM_LQ
|
||||||
|
status->cur_lq,
|
||||||
|
status->max_lq,
|
||||||
|
#endif
|
||||||
|
status->idle,
|
||||||
|
status->active,
|
||||||
|
status->total,
|
||||||
|
status->max_children_reached);
|
||||||
|
|
||||||
spprintf(content_type, 0, "Content-Type: application/json");
|
spprintf(content_type, 0, "Content-Type: application/json");
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,13 +14,15 @@ struct fpm_status_s {
|
||||||
int idle;
|
int idle;
|
||||||
int active;
|
int active;
|
||||||
int total;
|
int total;
|
||||||
|
unsigned cur_lq;
|
||||||
|
int max_lq;
|
||||||
unsigned long int accepted_conn;
|
unsigned long int accepted_conn;
|
||||||
unsigned int max_children_reached;
|
unsigned int max_children_reached;
|
||||||
struct timeval last_update;
|
struct timeval last_update;
|
||||||
};
|
};
|
||||||
|
|
||||||
int fpm_status_init_child(struct fpm_worker_pool_s *wp);
|
int fpm_status_init_child(struct fpm_worker_pool_s *wp);
|
||||||
void fpm_status_update_activity(struct fpm_shm_s *shm, int idle, int active, int total, int clear_last_update);
|
void fpm_status_update_activity(struct fpm_shm_s *shm, int idle, int active, int total, unsigned cur_lq, int max_lq, int clear_last_update);
|
||||||
void fpm_status_update_accepted_conn(struct fpm_shm_s *shm, unsigned long int accepted_conn);
|
void fpm_status_update_accepted_conn(struct fpm_shm_s *shm, unsigned long int accepted_conn);
|
||||||
void fpm_status_increment_accepted_conn(struct fpm_shm_s *shm);
|
void fpm_status_increment_accepted_conn(struct fpm_shm_s *shm);
|
||||||
void fpm_status_set_pm(struct fpm_shm_s *shm, int pm);
|
void fpm_status_set_pm(struct fpm_shm_s *shm, int pm);
|
||||||
|
|
|
@ -25,6 +25,7 @@ struct fpm_worker_pool_s {
|
||||||
char *user, *home; /* for setting env USER and HOME */
|
char *user, *home; /* for setting env USER and HOME */
|
||||||
enum fpm_address_domain listen_address_domain;
|
enum fpm_address_domain listen_address_domain;
|
||||||
int listening_socket;
|
int listening_socket;
|
||||||
|
int listening_queue_len;
|
||||||
int set_uid, set_gid; /* config uid and gid */
|
int set_uid, set_gid; /* config uid and gid */
|
||||||
int socket_uid, socket_gid, socket_mode;
|
int socket_uid, socket_gid, socket_mode;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue