Comparativa Apache2 & Nginx (php7, php-fpm, memcached, varnish)

Introducción

Antes de esta entrada, publique una muy relacionada donde trataba un pequeño estudio comparativo con contenido estático utilizando apache2 o nginx. Esto no es muy real por así decirlo, ya que en la mayoría de sitios webs que se sirven en la red, son aplicaciones web dinámicas (el contenido va variando según las llamadas del usuario). Por lo tanto, en esta entrada vamos a utilizar como referencia WordPress y asemejarnos lo más parecido a la mayoría de los casos que existen.

Comprobaremos el rendimiento de los servidores webs (Apache2 y Nginx) utilizando el módulo de php integrado con Apache2 y utilizando FPM-PHP que es una implementación alternativa que esta sobre todo pensado para proyectos con bastante tráfico. Una vez finalizado dicho estudio vamos a seleccionar la combinación “ganadora” en cuanto a rendimiento, y vamos a ver si podemos aumentar aún más dicho rendimiento utilizando (memcached y varnish).

Toda la entrada se desarrolla sobre una máquina con:

  • Debian Stretch 9
  • 2GB RAM

Instalación y Configuración Web

Apache2 con el módulo php

Instalación:

Crear un fichero php para comprobar el correcto funcionamiento del módulo php:

En /var/www/html/info.php, volcamos la siguiente linea dentro del fichero:

Reiniciamos el servicio:

Comprobamos desde el navegador web, introduciendo la dirección IP de la máquina seguido del nombre del fichero info.php:

Si nos fijamos en el campo Server API, la linea “Apache 2.0 Handler” nos indica que apache2 esta utilizando su propio módulo para interpretar el código php.

Apache2 con PHP-FPM

PHP-FPM es un proceso daemon con la unidad en systemd php7.0-fpm que corre un servidor FastCGI en el socket /var/run/php/php7.0-fpm.sock

Instalación:

Si tenemos el paquete de apache2 ya instalado, tendremos que deshabilitarlo:

Escuchando en un socket UNIX

La siguiente linea en el fichero /etc/php/7.0/fpm/pool.d/www.conf, por defecto viene para que escuche por socket unix:

Y en el fichero de configuración de php7-fpm, /etc/apache2/conf-available/php7.0-fpm.conf:

Nota: esto afectaría a todos los sitios webs que tuviéramos, si solo quisiéramos dicho comportamiento para un sitio web concreto, tendríamos que añadir esas lineas en el fichero de configuración del sitio.

Una vez añadido, activamos la configuración:

Activamos el módulo paraFastCGI:

Reiniciamos los servicios:

Misma comprobación que hicimos anteriormente con el módulo php de apache2, solo que esta vez tendremos que fijarnos que el campo Server Api habrá cambiado:

Y por último para confirmar que esta escuchando por el socket UNIX, ejecutamos:

Salida:

Escuchando en un socket TCP

Para que php-fpm empiece a escuchar por un puerto TCP, y no por un socket unix, deberemos comentar en el fichero /etc/apache2/conf-available/php7.0-fpm.conf, la linea anterior y agregar la nueva:

Y en el fichero /etc/php/7.0/fpm/pool.d/www.conf:

Por último reiniciar los servicios:

Confirmamos que esta escuchando por el puerto 9000 TCP:

Salida:

 

Nginx con PHP-FPM

Instalación:

Escuchando en un socket UNIX

Por defecto como hemos visto en php-fpm viene escuchando por socket unix, dejaríamos tal cual la linea en el fichero /etc/php/7.0/fpm/pool.d/www.conf:

Y añadimos la siguiente información en el fichero de configuración del sitio por defecto de nginx /etc/nginx/sites-enable:

 

Para comprobar que esta pillando la configuración nginx como hicimos con apache2, en /var/www/html/info.php, volcamos la siguiente linea dentro del fichero:

Nota: antes de comprobar el funcionamiento con nginx desde el navegador web ingresando la dirección IP de la máquina, detenemos el servicio de apache y lo deshabilitamos:

Ahora si desde el navegador, comprobamos el campo:

O incluso del sistema comprobamos:

Escuchando en un socket TCP

En el fichero /etc/php/7.0/fpm/pool.d/www.conf, sustituir el listen que viene por defecto, por:

Y modificamos el fichero de configuración del sitio web por defecto de nginx, dejandolo así:

Luego reiniciamos ambos servicios:

Comprobamos que ahora esta funcionando por un socket tcp:

 

Instalación de WordPress

La instalación de wordpress en apache2, la omito en esta entrada, ya que hay bastante información sobre ello en la red.

En Nginx

Instalamos los siguientes paquetes si no los teníamos ya instalados de antes:

Instalamos Mariadb:

Ejecutamos la siguiente instrucción e introducimos la contraseña para el usuario root:

Iniciamos sesión como root en la base de datos de Mariadb:

Ejecutamos las siguientes lineas:

Instalar php-fpm si no lo teníamos y algunos más:

Modificamos o añadimos los siguientes valores en /etc/php/7.0/fpm/pool.d/www.conf:

Ahora añadimos un nuevo bloque server o modificamos el default de nginx /etc/nginx/sites-available/default:

Normalmente viene habilitado el sitio default de nginx, si no fuera el caso o creáramos un nuevo, tendríamos que crear un enlace simbólico a:

Importante: usar rutas absolutas.

Para comprobar que no tenemos ningún error de sintaxis en el fichero de configuración:

Y reiniciaríamos los servicios:

Creamos un nuevo directorio en:

Descargamos wordpress y descomprimimos el comprimido en el directorio anterior:

Definimos correctamente los permisos de ese directorio y accedemos a la URL, http://DireccionIPdelaMaquina/wordpress:

Rellenaremos las 2 o 3 ventanas de instalación con los datos introducidos en los pasos anteriores y tendremos nuestro wordpress funcionando:

Nota: si nos da un error 404 al final de todos estos pasos, añadir la siguiente linea en el fichero de configuración del sitio web:

 

Estudio de rendimiento (Script en Python)

Como hicimos en la entrada comparativa con contenido estático, vamos a utilizar el script, para medir las peticiones por segundo que es capaz de responder ambos servidores webs y apache en 2 modos diferentes de interpretar código php.

El script que voy a utilizar es el siguiente.

Para cada combinación voy a indicar los cambios que habría que realizar en el script para su correcto funcionamiento:

Apache2 con php7

Como titulo le pondremos algo identificativo para saber que es el modo que estamos usando y con el servidor web apache, localhost, ya que el script se ejecuta desde la misma máquina, las urls son entradas de ejemplos que he creado con un contenido variado, y en la lista de servers, solo hay que reiniciar el servicio de apache, ya que usará el módulo de php integrado.

Salida del script:

Apache2 con PHP-FPM

Salida del script:

Con socket tcp:

Con socket unix:

 

Nginx con PHP-FPM

Salida del script:

Con socket tcp:

Con socket unix:

 

Resultado con gráfica de los resultados anteriores:

Nota: he seleccionado los resultados de PHP-FPM usando el socket unix.

Conclusión: si usamos el socket unix, se puede ver que al llegar a un nivel más alto de concurrencia, nginx destaca sobre apache2 considerablemente, en este caso a partir de las 100 conexiones concurrentes, nginx se crece y apache2 se mantiene al mismo rendimiento. De todas formas esto es una referencia y un acercamiento, habría que optimizar la configuración de ambos servidores y probar con cifras más elevadas.

 

Aumento de rendimiento a “Nginx con PHP-FPM”

Memcached

A la combinación ganadora en este caso Nginx con PHP-FPM vamos a configurarle memcached para ver si aumenta algo más el rendimiento :).

Instalar memcached y la extensión php:

Una vez instalado comprobamos que este corriendo el demonio en el servidor con el siguiente comando:

Para comprobar que la extensión de memcached esta configurada con el php7 podemos consultar el script que creamos anteriormente denominado info.php y consultar la siguiente información:

Abrimos el navegador http://DireccionIP/info.php:

Configurar Memcached con Socket UNIX

En Debian y derivados al instalar memcached, se añade un usuario al sistema llamado memcache, vamos a hacerlo miembro del grupo www-data:

Ahora abrimos el fichero de configuración /etc/memcached.conf y vamos a comprobar que están definidos los siguientes parámetros, ya que para que se comunique el plugin de WordPress que vamos a instalar con el memcached de la máquina deberá estar habilitado la escucha por TCP o aparecerá un mensaje de error como este:

Comprobamos estos valores en el fichero:

Reiniciamos el servicio:

Podemos ver si memcached esta funcionando, mostrando sus estádisticas:

Salida:

Configurar plugin WordPress Memcached para que use Sockets Unix

He probado con los plugins memcached is your friend y W3 Total Cache. Donde me he quedado con los resultados de W3 Total Cache, ya que ha mejorado algo el rendimiento de respuesta de nginx, con el otro plugin no he visto mejoría ninguna.

Instalamos dicho plugin desde el panel de administración de WordPress, lo activamos y seleccionamos que use como servidor memcached, si todo esta correcto os aparecerá unas notificaciones así:

Por último reiniciar también los servicios:

Ahora vamos a ejecutar el script para ver el resultado de esta configuración, para ello vamos a cambiar un par de detalles en el código del script:

Resultado:

 

Varnish Cache

Instalar varnish:

Ahora vamos a editar el fichero de configuración /etc/default/varnish indicando el puerto 80:

Posteriormente vamos a indicarle en la unidad de systemd que se ejecute también en el puerto 80:

Reiniciar los servicios:

Confirmamos que varnish esta escuchando en el puerto 80 y nginx en el 8080:

Salida:

Aquí el fichero de configuración del sitio de wordpress de nginx:

Por último he tenido que descomentar esta línea ya que el comando ab, para testear las conexiones concurrentes, se paraba debido a que nginx cortaba al llegar al limite:

Comprobación de varnish, con el siguiente comando podemos ver las estadísticas:

Aquí las lineas que he modificado en el script:

Resultado:

 

 

Gráfica comparativa con los 3 modos en Nginx

Teniendo en cuenta que la configuración ha sido la predeterminada a salvo de lo que hayamos configurado en cada servidor, el resultado ha sido el siguiente:

 

 

Volviendo al tema de que el escenario no es muy real, esto es simplemente para tomar una referencia, ya que normalmente las peticiones que se realizan al servidor web, son externas y no desde la propia máquina, en la mayoría de los casos.

Aún así espero que os sirva de referencia y nos vemos en la siguiente entrada 😉

Referencias:

https://httpd.apache.org/docs/2.4/mod/mod_proxy_fcgi.html

http://www.digitalvalley.com/blog/utilizar-varnish-y-nginx-en-nuestra-instalacion-de-wordpress/

 

 

 

 

Autor entrada: CharlieJ

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *