Largos tiempos de espera antes de la respuesta del servidor Apache 2.2 (Gentoo LAMP)

9

Recientemente he movido el sitio web de un cliente (usando el CMS concrete5) a un VPS que ejecuta Gentoo, Apache 2.2, PHP5 y MySQL 5 y he notado que los tiempos de respuesta de Apache son bastante malos (era lo mismo en el servidor anterior) , a veces hasta 8-9 segundos, pero más a menudo entre 300 ms y 3 segundos (hacia 300 ms, no me importa). Sé que no es latencia de red, ya que el servidor tiene un ping (desde mi ubicación) de alrededor de 30 ms.

Aquí hay un ejemplo de los tiempos (puede ver que es rápido después de la espera inicial):

Línea de tiempo del panel de Firebug Net

Estoy ejecutando APC (aunque no estoy seguro de que funcione correctamente ...) y SuExec. Los módulos de Apache son:

 core_module (static)
 authn_file_module (static)
 authn_default_module (static)
 authz_host_module (static)
 authz_groupfile_module (static)
 authz_user_module (static)
 authz_default_module (static)
 auth_basic_module (static)
 include_module (static)
 filter_module (static)
 deflate_module (static)
 log_config_module (static)
 env_module (static)
 expires_module (static)
 headers_module (static)
 setenvif_module (static)
 version_module (static)
 ssl_module (static)
 mpm_prefork_module (static)
 http_module (static)
 mime_module (static)
 status_module (static)
 autoindex_module (static)
 asis_module (static)
 info_module (static)
 suexec_module (static)
 cgi_module (static)
 negotiation_module (static)
 dir_module (static)
 actions_module (static)
 userdir_module (static)
 alias_module (static)
 rewrite_module (static)
 so_module (static)
 suphp_module (shared)

y los módulos PHP son:

bcmath
calendar
ctype
curl
db
dbase
domxml
exif
ftp
gd
gettext
iconv
imap
mbstring
mcrypt
mime_magic
mysql
openssl
overload
pcre
posix
session
standard
sysvsem
sysvshm
tokenizer
xml
xslt
zlib

Tengo gzip habilitado en todos los archivos relevantes.

Apache se ejecuta con prefork, y la configuración en httpd.conf es:

<IfModule prefork.c>
StartServers         10
MinSpareServers      10
MaxSpareServers      20
MaxClients           250
MaxRequestsPerChild  4000
</IfModule>

HostnameLookups Off

Me he dado cuenta de que las páginas que (creo) son pesadas en bases de datos, como el Tablero del CMS, suelen ser más lentas. Pensé que esto podría significar que MySQL podría optimizarse. También me preguntaba acerca de los módulos de Apache: me confundo entre mod_php5, mod_cgi, mod_fastcgi, etc., hay consejos contradictorios en toda la red sobre cuál es el mejor para usar.

Aquí está la salida de MySQLTuner :

-------- General Statistics --------------------------------------------------
[--] Skipped version check for MySQLTuner script
[OK] Currently running supported MySQL version 5.0.44-log
[OK] Operating on 64-bit architecture

-------- Storage Engine Statistics -------------------------------------------
[--] Status: -Archive -BDB -Federated -InnoDB -ISAM -NDBCluster
[--] Data in MyISAM tables: 35M (Tables: 161)
[!!] Total fragmented tables: 15

-------- Security Recommendations  -------------------------------------------
[OK] All database users have passwords assigned

-------- Performance Metrics -------------------------------------------------
[--] Up for: 3d 21h 44m 16s (293K q [0.868 qps], 1K conn, TX: 135M, RX: 90M)
[--] Reads / Writes: 99% / 1%
[--] Total buffers: 58.0M global + 1.6M per thread (100 max threads)
[!!] Maximum possible memory usage: 219.7M (93% of installed RAM)
[OK] Slow queries: 0% (0/293K)
[OK] Highest usage of available connections: 2% (2/100)
[OK] Key buffer size / total MyISAM indexes: 16.0M/20.9M
[OK] Key buffer hit rate: 99.6% (5M cached / 21K reads)
[!!] Query cache is disabled
[OK] Sorts requiring temporary tables: 0% (0 temp sorts / 3K sorts)
[!!] Temporary tables created on disk: 47% (2K on disk / 5K total)
[!!] Thread cache is disabled
[!!] Table cache hit rate: 6% (64 open / 1K opened)
[OK] Open file limit used: 12% (128/1K)
[OK] Table locks acquired immediately: 100% (356K immediate / 356K locks)

-------- Recommendations -----------------------------------------------------
General recommendations:
    Run OPTIMIZE TABLE to defragment tables for better performance
    Reduce your overall MySQL memory footprint for system stability
    Enable the slow query log to troubleshoot bad queries
    When making adjustments, make tmp_table_size/max_heap_table_size equal
    Reduce your SELECT DISTINCT queries without LIMIT clauses
    Set thread_cache_size to 4 as a starting value
    Increase table_cache gradually to avoid file descriptor limits
Variables to adjust:
  *** MySQL's maximum memory usage is dangerously high ***
  *** Add RAM before increasing MySQL buffer variables ***
    query_cache_size (>= 8M)
    tmp_table_size (> 32M)
    max_heap_table_size (> 16M)
    thread_cache_size (start at 4)
    table_cache (> 64)

Noté que cuando se cargó una página con gran cantidad de DB, el uso de la CPU aumentó al 57% (usando la parte superior), lo que sugiere que hay algunas cosas MySQL mal optimizadas o que el almacenamiento en caché es absolutamente necesario para acelerar esta configuración.

Cualquier ayuda sería muy apreciada!

melat0nin
fuente
2
Solo un pensamiento: ¿está HostnameLookuphabilitada la configuración de registro? Si es así, la búsqueda de DNS del cliente solicitante que se agregará al registro de acceso puede ser muy lenta (o el primer servidor DNS incluso agota el tiempo de espera), lo que puede ralentizar la solicitud completa.
jCoder
Está deshabilitado: lo
agregaré
Si solo se trata de solicitudes relacionadas con PHP. Verifique la fragmentación en APC. También debe monitorear de cerca el uso de los recursos; ¿El servidor está utilizando todos sus recursos o está inactivo?
Kvisle
Ya estoy (ver OP) :)
melat0nin
Perdón por eso :) - actualicé mi comentario; ¿Ha verificado si solo se trata de solicitudes PHP u otras solicitudes también? ¿El servidor está inactivo o ocupado? ¿APC está fragmentado o no? ¿Cuánta memoria se 'almacena en caché' frente a otras cosas?
Kvisle

Respuestas:

14

¿Sabes exactamente de qué se cuelgan los procesos de los trabajadores de Apache? Prueba esto para ver:

mkdir /strace; ps auxw | grep httpd | awk '{print"-p " $2}' | xargs strace -o /strace/strace.log -ff -s4096 -r

Cargue algunas páginas nuevas (es decir, no en caché local) en su navegador, CTRL + C para detener strace y luego ordene strace.logs por el tiempo dedicado a cada llamada:

for i in `ls /strace/*`; do echo $i; cat $i | cut -c11-17 | sort -rn | head; done

Vea cualquier strace.logs con llamadas de más de 1.0 segundo y busque por hora desde la salida del comando anterior. Esto le indicará el paso exacto en el que se están colgando.

¿Por cambio tiene instalado un firewall como CSF? Vi este mismo problema en un VPS. Al depurar procesos httpd con strace, las llamadas de gettimeofday demoraban hasta 5 segundos o más. Curiosamente reduje esto a CSF, que estaba tratando de filtrar la interfaz venet0, una interfaz de bucle invertido en contenedores OpenVZ o Virtuozzo. Establecer este parámetro en /etc/csf/csf.conf lo arregló principalmente para mí:

"ETH_DEVICE_SKIP = "venet0,lo"

Digo sobre todo porque a veces todavía hay 500-1000 ms de espera para que se establezcan las conexiones, pero es una gran mejora de más de 5000.

reflexiv
fuente
1
¡Gracias por tu respuesta! Al final, las cosas parecían estar ordenadas cuando conseguí que APC funcionara correctamente: el sitio ahora es bastante ágil. Sin embargo, hace +1 para obtener instrucciones excelentes, y las tomaré en cuenta en caso de que vuelva a encontrar algo como esto.
melat0nin
3

Aquí hay un excelente manual / tutorial para solucionar este tipo de problemas utilizando strace.

Maximum possible memory usage: 219.7M (93% of installed RAM)

¿Debe ser una caja VPS de gama baja?

  • Es posible que desee marcar su configuración de MySQL
  • Sintonice Apache para reducir la cantidad de horquillas httpd
  • Comprueba si puedes habilitar el intercambio
  • ¿APC está configurado para almacenar automáticamente en caché los códigos de operación? Verifique usando el script 'apc.php' distribuido con apc.
hielo delgado
fuente
3

Debe separar Network, Apache, MySQL y PHP como fuentes de latencia.

Si puede extraer una imagen de Apache rápidamente (muy poco tiempo para el primer byte), entonces la red y Apache generalmente están bien.

Si puede extraer una página con solo una declaración phpinfo (), normalmente PHP está bien (puede necesitar algunos ajustes).

Si escribe una prueba de conexión de base de datos simple y es rápida, entonces esa capa generalmente también está bien.

Por último, abra la página de la aplicación. Si es lento, entonces el problema es interno al procesamiento de las aplicaciones. Si bien el ajuste puede ayudar, esto es mucho más difícil de resolver.

Sin perfilar la aplicación, puede ser difícil encontrar el problema. Herramientas como NewRelic pueden ayudar con este problema, pero no son una cura.

¿Su aplicación tiene algún tipo de depuración interna para mostrar dónde se está gastando el tiempo?

jeffatrackaid
fuente
0

sugiero agregar una medición del tiempo de renderizado y verificar cuánto tiempo le toma al servidor renderizar la página HTML pura. Entonces sabes si está en el CMS o en otro lugar. Apuesto a que mi 2cent no es la configuración de su servidor. / maddin

maddin
fuente
¿Puedes sugerir un método para medir el tiempo de renderizado? ¿Es suficiente el panel Net de Firebug en una página HTML estática?
melat0nin