Introducción

A través de esta práctiva vamos a echarle un vistazo a las distintas configuraciones que nos permitirán la ejecución de código php y en los servidores web de apache 2.4 y nginx, analizando en cada caso con cuál obtenemos un mayor rendimiento en base a un mayor número de peticiones concurrentes.

Ejecución de scripts php

Para realizar esta tarea de la práctica vamos a preparar cinco configuraciones:

Vamos a instalar en la misma máquina los siguientes paquetes:

apt install mariadb-server apache2 nginx libapache2-mod-php php-fpm php php-mysql php-curl php-gd php-mbstring php-xml php-xmlrpc php-soap php-intl php-zip

Descargamos e instalamos wordpress con su respectiva base de datos. Para modificar el tamaño máximo de los ficheros que podemos subir, nos tenemos que dirigir a /etc/php/7.3/apache2/php.ini y modificar la siguiente lineas:

...

; Maximum size of POST data that PHP will accept.
; Its value may be 0 to disable the limit. It is ignored if POST data reading
; is disabled through enable_post_data_reading.
; http://php.net/post-max-size
post_max_size = 512M

...

; Maximum allowed size for uploaded files.
; http://php.net/upload-max-filesize
upload_max_filesize = 512M

...

Tamaño cambiado:

!size-wp-mod.png!

Dependiendo de qué estemos utilizando para ejecutar el código php, la ruta del fichero php.ini será /etc/php/7.3/apache, /etc/php/7.3/fpm, etc.

Módulo php7-apache2

Apache2 con php-fpm socket unix

Para cambiar a php-fpm, tenemos que deshabilitar el módulo de php7.3 y activar el módulo de proxy_fcgi. También tendremos que desactivar el módulo de mpm_prefork y activar mpm_event.

a2dismod php7.3
a2enmod proxy_fcgi
a2dismod mpm_prefork
a2enmod mpm_event

Pruebas

Apache2 con php-fpm socket tcp/ip

Para cambiar el socket a tcp/ip nos dirigimos primero al fichero /etc/php/7.3/fpm/pool.d/www.conf y cambiamos la siguiente linea:

;listen = /run/php/php7.3-fpm.sock
listen = 127.0.0.1:9000

Y reiniciamos el servicio

systemctl restart php7.3-fpm

Pruebas

Nginx con php-fpm socket unix

Iniciamos nginx, y como tiene el mismo documentroot que apache, no necesitamos modificar demasiadas cosas en el fichero del virtualhost. Tan solo descomentaremos las lineas de fastcgi_pass:

location ~ \.php$ {
include snippets/fastcgi-php.conf;

# With php-fpm (or other unix sockets):
fastcgi_pass unix:/run/php/php7.3-fpm.sock;
# With php-cgi (or other tcp sockets):
#       fastcgi_pass 127.0.0.1:9000;
}

También tendremos que definir un nombre para el servidor, en mi caso lo llamaré pruebawordpress.com

Pruebas

Nginx con php-fpm socket tcp/ip

Cambiamos la configuración del virtualhost de socket unix a socket tcp/ip:

        location ~ \.php$ {
                include snippets/fastcgi-php.conf;

                # With php-fpm (or other unix sockets):
        #        fastcgi_pass unix:/run/php/php7.3-fpm.sock;
                # With php-cgi (or other tcp sockets):
               fastcgi_pass 127.0.0.1:9000;
        }

Y de igual forma modificamos el fichero /etc/php/7.3/fpm/pool.d/www.conf tal y como hicimos antes.

Pruebas

Aumento de rendimiento en la ejecución de scripts PHP

Memcached

Como hemos podido comprobar hemos obtenido el mejor resultado con la combinación de PHP-FPM (socket unix) + nginx. No obstante, todavía podemos optimizar algo más el rendimiento utilizando el paquete memcached. Los paquetes a instalar son los siguientes:

apt install memcached php-memcached

Después nos dirigimos al fichero de configuración ubicado en /etc/memcached.conf y cambiamos las siguientes lineas para que nos quede algo así:

 
# memcached default config file
# 2003 - Jay Bonci <jaybonci@debian.org>
# This configuration file is read by the start-memcached script provided as
# part of the Debian GNU/Linux distribution.

# Run memcached as a daemon. This command is implied, and is not needed for the
# daemon to run. See the README.Debian that comes with this package for more
# information.
-d

# Log memcached's output to /var/log/memcached
logfile /var/log/memcached.log

# Be verbose
# -v

# Be even more verbose (print client commands as well)
# -vv

# Start with a cap of 64 megs of memory. It's reasonable, and the daemon default
# Note that the daemon will grow to this size, but does not start out holding this much
# memory
-m 64

# Default connection port is 11211
#-p 11211

# Run the daemon as root. The start-memcached will default to running as root if no
# -u command is present in this config file
-u memcache

# Specify which IP address to listen on. The default is to listen on all IP addresses
# This parameter is one of the only security measures that memcached has, so make sure
# it's listening on a firewalled interface.
#-l 127.0.0.1

#Añadimos el socket y los permisos

-s /var/run/memcached/memcached.sock
-a 775


# Limit the number of simultaneous incoming connections. The daemon default is 1024
# -c 1024

# Lock down all paged memory. Consult with the README and homepage before you do this
# -k

# Return error when memory is exhausted (rather than removing items)
# -M

# Maximize core file limit
# -r

# Use a pidfile
-P /var/run/memcached/memcached.pid

Acto seguido modificamos al usuario memcache y lo añadimos al grupo www-data y reiniciamos el servicio

 
 usermod -g www-data memcache
 systemctl restart memcached

Y comprobamos que se ha creado el socket ejecutando ls -l /var/run/memcached/

$ ls -l /var/run/memcached/
total 4
-rw-r--r-- 1 memcache www-data 5 Jan 21 08:33 memcached.pid
srwxrwxr-x 1 memcache www-data 0 Jan 21 08:33 memcached.sock

Pruebas

Como podemos observar hemos obtenido una mejora significativa en el rendimiento. Sin memcached, en las 1000 peticiones concurrentes obtuvimos 3109, mientras que con memcached instalado hemos rebajado hasta 1918, casi la mitad!

Varnish

Otro método para mejorar nginx es el uso del proxy inverso Varnish. Primero instalamos el paquete con apt y luego nos dirigimos a los ficheros de configuración. Abrimos el fichero /etc/varnish/default.vcl y modificamos los siguientes apartados para que queden así:

sub vcl_recv {
    unset req.http.cookie;
}
sub vcl_fetch {
    unset beresp.http.set-cookie;
}

Despues modificamos el fichero /etc/default/varnish, cambiando la el parámetro -a de la directiva DAEMON_OPTS para que escuche por el puerto 80, quedando de la siguiente forma:

DAEMON_OPTS="-a :80
             -T localhost:6082
             -f /etc/varnish/default.vcl
             -S /etc/varnish/secret
             -s malloc,256M"

Además tendremos que modificar el fichero de configuración de la unidad de systemd para que cambie definitivamente el puerto. La unidad de systemd está ubicada en /lib/systemd/system/varnish.service y tendremos que modificar la directiva ExecStart para que quede algo así:

ExecStart=/usr/sbin/varnishd -j unix,user=vcache -F -a :80 -T localhost:6082 -f /etc/varnish/default.vcl -S /etc/varnish/secret -s malloc,256m

Por último cambiamos el puerto de escucha de nginx al 8080. Para ello cambiamos el parámetro listen del fichero de configuración del virtualhost y luego reiniciamos ambos servicios.

...
        listen 8080;
        listen [::]:8080;
...

Pruebas