El sitio se vuelve inaccesible debido a la cola de escucha PHP-FPM, la CPU toca el 100%

5 minutos de lectura

avatar de usuario
pequeñolebowski

Me he estado devanando los sesos tratando de resolver este problema que surge aleatoriamente cada pocas horas en mi servidor de producción que aloja un solo blog de WordPress (con un tráfico decente: 2000 usuarios en tiempo real en días promedio, más de 5000 en días buenos, páginas vistas por minuto varía de 300 a 700+).

Uso Newrelic para monitorear el rendimiento y noté algo peculiar:

Cada pocas horas (al azar), el estado del grupo de PHP-FPM es similar al siguiente (estado real tomado ayer)

pool:                 www
process manager:      static
start time:           02/Jan/2017:05:03:16 -0500
start since:          27290
accepted conn:        1107594
listen queue:         777
max listen queue:     794
listen queue len:     40000
idle processes:       0
active processes:     100
total processes:      100
max active processes: 101
max children reached: 0
slow requests:        0

reiniciando PHP-FPM y nginx resuelve el problema, pero vuelve a suceder en un par de horas. Cualquier ayuda es apreciada. Por favor guíame.


Configuración del servidor:

DigitalOcean 48GB Memory
16 Core Processor
480GB SSD Disk

Configuración del grupo PHP-FPM:

pm = static
pm.max_children = 100
pm.max_requests = 5000

configuración nginx:

worker_processes  32;
worker_rlimit_nofile 100000;
events {
    worker_connections  40000;
    use epoll;
    multi_accept on;
}

yo también estoy usando xcache, varnish con W3TC en WordPress. (también tienen Cloudflare)

sysctl.conf:

# Increase size of file handles and inode cache
fs.file-max = 2097152

# Do less swapping
vm.swappiness = 10
vm.dirty_ratio = 60
vm.dirty_background_ratio = 2

### GENERAL NETWORK SECURITY OPTIONS ###

# Number of times SYNACKs for passive TCP connection.
net.ipv4.tcp_synack_retries = 2

# Allowed local port range
net.ipv4.ip_local_port_range = 2000 65535

# Protect Against TCP Time-Wait
net.ipv4.tcp_rfc1337 = 1

# Decrease the time default value for tcp_fin_timeout connection
net.ipv4.tcp_fin_timeout = 15

# Decrease the time default value for connections to keep alive
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_keepalive_probes = 5
net.ipv4.tcp_keepalive_intvl = 15

### TUNING NETWORK PERFORMANCE ###

# Default Socket Receive Buffer
net.core.rmem_default = 31457280

# Maximum Socket Receive Buffer
net.core.rmem_max = 12582912

# Default Socket Send Buffer
net.core.wmem_default = 31457280

# Maximum Socket Send Buffer
net.core.wmem_max = 12582912

# Increase number of incoming connections
net.core.somaxconn = 40000

# Increase number of incoming connections backlog
net.core.netdev_max_backlog = 65536

# Increase the maximum amount of option memory buffers
net.core.optmem_max = 25165824

# Increase the maximum total buffer-space allocatable
# This is measured in units of pages (4096 bytes)
net.ipv4.tcp_mem = 65536 131072 262144
net.ipv4.udp_mem = 65536 131072 262144

# Increase the read-buffer space allocatable
net.ipv4.tcp_rmem= 10240 87380 12582912
net.ipv4.udp_rmem_min = 16384

# Increase the write-buffer-space allocatable
net.ipv4.tcp_wmem= 10240 87380 12582912
net.ipv4.udp_wmem_min = 16384

# Increase the tcp-time-wait buckets pool size to prevent simple DOS attacks
net.ipv4.tcp_max_tw_buckets = 1440000
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1

  • He tenido algunos problemas extraños con bloqueos de sesión en instalaciones de WordPress con PHP-FPM en el pasado. Se produciría un interbloqueo en la sesión debido a múltiples solicitudes. Esto fue hace muchos años… dudo que sea el mismo problema que tienes… pero podría haber algún otro recurso que esté ocupado. ¿Puedes describir tu configuración con más detalle? ¿Está utilizando sockets Unix para PHP-FPM o TCP? ¿Qué está utilizando para la base de datos y el almacenamiento de sesión? ¿Qué versiones de todo? Finalmente, las versiones anteriores del agente de Newrelic me han causado muchos problemas en el pasado… asegúrese de que esté actualizado.

    – brad

    3 de enero de 2017 a las 7:13

  • Intenta ver si puedes diseccionar el problema un poco más. ¿Alguna otra señal de advertencia? ¿Se acumulan las conexiones de la base de datos? ¿Redis, o lo que sea que esté usando para las sesiones, en demasiadas conexiones? E/S de disco? También considere publicar en ServerFault.com. Muchos problemas de Nginx/PHP-FPM aterrizan ahí. (Pero esto también está perfectamente relacionado con Stack Overflow).

    – brad

    3 de enero de 2017 a las 7:16

  • Detalles agregados a la pregunta, @Brad. Estoy revisando los registros, pero no recibo ningún registro de advertencia. Extraño. Déjame publicarlo en ServerFault también. ¿Alguna idea después de mirar la configuración? ¿Estoy haciendo algo mal aquí?

    – Pequeño Lebowski

    3 de enero de 2017 a las 7:26

Intente detener a su agente de NewRelic y espere unas horas para ver si eso resuelve el problema. Si es así, intente actualizarlo a la última versión. Si vuelve una vez que se actualizó, comuníquese con el soporte de NewRelic.

Compruebe max_execution_time y request_terminate_timeout en su php.ini.

Compruebe también los valores proxy_connect_timeout, proxy_send_timeout, proxy_read_timeout y send_timeout en la configuración de Nginx.

Recomendaría verificar la configuración de TCP/IP para ver cuáles son, ya que es posible que sea necesario reducir la configuración de mantenimiento activo y de tiempo de espera. He visto que algunas distribuciones vienen con un minuto o más por defecto.

También debe verificar que el tráfico del agente de escucha sea tráfico válido. Vea si puede enviar muestras a un archivo y validar que el tráfico sea legítimo. Muchos procesos automatizados buscan instancias de WordPress en interwebz. Estos bots pueden causar todo tipo de problemas al piratear su sitio.

¿Ha revisado su access.log o domain.com.access.log en /var/log/nginx/? Mirando eso, tendrá más detalles de por qué PHP-FPM se está comiendo su CPU.

Creo que su sitio web está en una fuerza bruta para wp-login.php, eso consume una gran cantidad de CPU.

¿Ha sido útil esta solución?