Prueba de desempeño y stress para Apache, Nginx or IIS

Escrito por:
Fecha: 2012-05-15 14:25:00 00:00

Si estas usando un servidor web, ya sea este Apache, Nginx, lighthttpd, Cherokee o incluso IIS (que no recomiendo), debes querer saber como se desempeña bajo una fuerte carga.

Cualquiera de los anteriormente mencionados servidores web, reaccionaran bien, con los parámetros por defecto, pero cuando tu sitio es listado en menéame.net, o tu página se vuelve viral en Twitter o Facebook, entonces, puedes estar en problemas y desilusionar a tus visitantes.

Lo mejor que puedes hacer es probar tu sitio, y simular grandes cargas de trabajo, para que puedas ajustar las configuraciones del servidor que te encuentres usando, y así puedas soportar la carga en ese gran día.

Vamos a usar ab para realizar la prueba.

Veamos que es lo que necesitamos:

  • Servidor a ser probado
    • Archivo html
    • Archivo PHP
    • Archivo de imagen (puede ser png o jpg)
  • Otro servidor con Apache instalado, desde este correremos las pruebas, debe haber suficiente ancho de banda disponible entre ambos, para que los resultados no sean sesgados. De ser posible, ambos servidores deben estar en el mismo Data Center.

He aquí el contenido de los archivos arriba listados:

El Archivo HTML

 <html>
 <title>Simple HTML file for testing server</title>
 <h1>Heading number 1</h1>
 <p>With this file I will test an Apache server</p>
 <p><a href="http://bitacora.garron.me/linux/">Linux</p>
 </html>

El Archivo PHP

 <html>
 <Title>PHP info</title>
 <?php

      // Lista información de PHP
      phpinfo();

      // Muestra información de los módulos
      phpinfo(INFO_MODULES);

  ?>
  </html>

El Archivo de Imagen

El archivo de imagen es un archivo jpg de 72.252 bytes.

Corriendo la prueba

Se alojan los tres archivos en un directorio de tu servidor web y corres las siguientes pruebas:

 ab -kc 1000 -n 10000 http://www.some-site.cc/tmp/index.html

Eso enviará 1.000 sesiones concurrentes 10.000 veces, y los resultados son:

 This is ApacheBench, Version 2.0.41-dev <$Revision: 1.141 $> apache-2.0       
 Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/  
 Copyright (c) 2006 The Apache Software Foundation, http://www.apache.org/     
 
 Benchmarking www.some-site.cc (be patient)
 Completed 1000 requests
 Completed 2000 requests
 Completed 3000 requests
 Completed 4000 requests
 Completed 5000 requests
 Completed 6000 requests
 Completed 7000 requests
 Completed 8000 requests
 Completed 9000 requests
 Finished 10000 requests
 
 
 Server Software:        Apache/2.2.9
 Server Hostname:        www.some-site.cc
 Server Port:            80
 
 Document Path:          /tmp/index.html
 Document Length:        207 bytes
 
 Concurrency Level:      1000
 Time taken for tests:   6.571282 seconds
 Complete requests:      10000
 Failed requests:        0
 Write errors:           0
 Keep-Alive requests:    9923
 Total transferred:      5744865 bytes
 HTML transferred:       2083869 bytes
 Requests per second:    1521.77 [#/sec] (mean)
 Time per request:       657.128 [ms] (mean)
 Time per request:       0.657 [ms] (mean, across all concurrent requests)
 Transfer rate:          853.71 [Kbytes/sec] received
 
 Connection Times (ms)
               min  mean[+/-sd] median   max
 Connect:        0    3  26.1      0     225
 Processing:     1   69 482.3     12    5947
 Waiting:        0   68 482.3     12    5946
 Total:          1   72 504.3     12    6143
 
 Percentage of the requests served within a certain time (ms)
   50%     12
   66%     17
   75%     21
   80%     21
   90%     37
   95%     39
   98%    130
   99%   2647
  100%   6143 (longest request)

Hagamos lo mismo con el archivo PHP, y los resultados son:

This is ApacheBench, Version 2.0.41-dev <$Revision: 1.141 $> apache-2.0      
Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ 
Copyright (c) 2006 The Apache Software Foundation, http://www.apache.org/    

Benchmarking www.some-site.cc (be patient)
Completed 1000 requests                   
Completed 2000 requests                   
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Finished 10000 requests


Server Software:        Apache/2.2.9
Server Hostname:        www.some-site.cc
Server Port:            80

Document Path:          /tmp/index.php
Document Length:        62446 bytes

Concurrency Level:      1000
Time taken for tests:   157.530617 seconds
Complete requests:      10000
Failed requests:        21
   (Connect: 0, Length: 21, Exceptions: 0)
Write errors:           0
Keep-Alive requests:    0
Total transferred:      628658346 bytes
HTML transferred:       626254006 bytes
Requests per second:    63.48 [#/sec] (mean)
Time per request:       15753.062 [ms] (mean)
Time per request:       15.753 [ms] (mean, across all concurrent requests)
Transfer rate:          3897.17 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0 3898 9601.3    132   93114
Processing:   711 4816 9077.5   2852  151641
Waiting:       96 4079 8403.1   2434  147921
Total:        964 8715 13258.0   4959  152406

Percentage of the requests served within a certain time (ms)
  50%   4959
  66%   6265
  75%   8895
  80%  11189
  90%  19319
  95%  25519
  98%  50649
  99%  69027
 100%  152406 (longest request)

Y finalmente con la imagen:

 This is ApacheBench, Version 2.0.41-dev <$Revision: 1.141 $> apache-2.0               
 Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/          
 Copyright (c) 2006 The Apache Software Foundation, http://www.apache.org/             
 
 Benchmarking www.some-site.cc (be patient)
 Completed 1000 requests
 Completed 2000 requests
 Completed 3000 requests
 Completed 4000 requests
 Completed 5000 requests
 Completed 6000 requests
 Completed 7000 requests
 Completed 8000 requests
 Completed 9000 requests
 Finished 10000 requests
 
 
 Server Software:        Apache/2.2.9
 Server Hostname:        www.some-site.cc
 Server Port:            80
 
 Document Path:          /tmp/38_TaylorSwift.jpg
 Document Length:        72252 bytes
 
 Concurrency Level:      1000
 Time taken for tests:   30.131674 seconds
 Complete requests:      10000
 Failed requests:        0
 Write errors:           0
 Keep-Alive requests:    10000
 Total transferred:      730617980 bytes
 HTML transferred:       726894150 bytes
 Requests per second:    331.88 [#/sec] (mean)
 Time per request:       3013.167 [ms] (mean)
 Time per request:       3.013 [ms] (mean, across all concurrent requests)
 Transfer rate:          23679.20 [Kbytes/sec] received
 
 Connection Times (ms)
               min  mean[+/-sd] median   max
 Connect:        0    5  49.6      0     552
 Processing:   311  440 153.4    422    5346
 Waiting:        7  190 172.0    201    4912
 Total:        311  446 184.0    422    5898
 
 Percentage of the requests served within a certain time (ms)
   50%    422
   66%    433
   75%    455
   80%    460
   90%    474
   95%    496
   98%    566
   99%    820
  100%   5898 (longest request)

Vamos ahora con las partes mas relevantes de los resultados y expliquemos un poco su significado.

Para el archivo html Requests per second: 1521.77 [#/sec] (mean) Time per request: 657.128 [ms] (mean) Para el archivo PHP Requests per second: 63.48 [#/sec] (mean) Time per request: 15753.062 [ms] (mean) Para el archivo de imagen Requests per second: 331.88 [#/sec] (mean) Time per request: 3013.167 [ms] (mean)

Como pueden ver, para el archivo html, se sirven 1.521 peticiones por segundo, para la imagen 331 y para el php solo 63, esto es porque, el PHP requiere de mucho más trabajo del procesador y esto hace que cada requerimiento se sirva mas lento, lo que pone en cola muchos requerimientos al servidor, haciendo que incluso algunos no sean atendidos.

He aquí una imagen de los resultados de htop, cuando se esta corriendo la prueba sobre el archivo PHP

imagen top htop de apache bajo stress

Algo que pueden hacer, es instalar cache de algún tipo, como ser APC. Ese seria el más efectivo para este caso, aunque varnish también puede ayudar bastante. Lo bueno es que ya saben como probar en cada fase de su configuración.