Vamos a comparar el rendimiento de distintas configuraciones de servidores web sirviendo páginas dinámicas programadas con PHP, en concreto vamos a servir un CMS WordPress.
Las configuraciones que vamos a realizar son las siguientes:
Módulo php5-apache2
FPM-PHP + apache2
FPM-PHP + nginx
WordPress
Para esta tarea he creado una máquina llamada happy basada en Debian 9.1.
Tarea 1 (1 punto)(Obligatorio): Documenta la instalación del módulo php de apache2. Muestra wordpress funcionando con el módulo php de apache2. Realiza una comprobación de que, efectivamente, se está usando el módulo php.
Módulo php
Lo primero es crear el servidor LAMP:
root@happy:/home/debian# apt install apache2 php7.0 mysql-server
Lo siguiente es acitvar e módulo php:
root@happy:/home/debian# a2enmod php7.0
Para que nos muestre la info de php, creamos el fichero siguiente con esas 3 lineas
root@happy:/home/debian# nano /var/www/html/info.php
WordPress
Tarea 2 (1 punto)(Obligatorio): Documenta la instalación y configuración de FPM-PHP y apache2 (escuchando en un socket UNIX) con el módulo de multiprocesamiento event. Muestra wordpress funcionando con FPM-PHP. Realiza una comprobación de que, efectivamente, se está usando FPM-PHP.
INSTALACIÓN:
root@happy:/home/debian# apt install php7.0-fpm php7.0
NOTICE: Not enabling PHP 7.0 FPM by default. NOTICE: To enable PHP 7.0 FPM in Apache2 do: NOTICE: a2enmod proxy_fcgi setenvif NOTICE: a2enconf php7.0-fpm NOTICE: You are seeing this message because you have apache2 package installed.
Par activar el módulo fpm:
root@happy:/home/debian# a2enmod proxy_fcgi setenvif root@happy:/home/debian# a2enconf php7.0-fpm root@happy:/home/debian# systemctl restart apache2
CONFIGURACIÓN:
En /etc/php/7.0/fpm/pool.d/www.conf descomentamos la línea de status y comprobamos en la línea de listen que esté de esta forma:
listen = /run/php/php7.0-fpm.sock pm.status_path = /status
Para activar mpm_event:
root@happy:/home/debian# a2enmod mpm_event Considering conflict mpm_worker for mpm_event: Considering conflict mpm_prefork for mpm_event: ERROR: Module mpm_prefork is enabled - cannot proceed due to conflicts. It needs to be disabled first!
Nos dice que worker y prefork están activados, asi que los desactivamos
root@happy:/home/debian# a2dismod mpm_worker Module mpm_worker already disabled root@happy:/home/debian# a2dismod mpm_prefork ERROR: The following modules depend on mpm_prefork and need to be disabled first: php7.0
Prefork depende de php7.0, pr lo que primero hay que desactivarlo y luego prefork:
root@happy:/home/debian# a2dismod php7.0 root@happy:/home/debian# a2dismod mpm_prefork root@happy:/home/debian# a2enmod mpm_event Considering conflict mpm_worker for mpm_event: Considering conflict mpm_prefork for mpm_event: Enabling module mpm_event. To activate the new configuration, you need to run: systemctl restart apache2 root@happy:/home/debian# systemctl restart apache2
Para ver que estamos con event:
root@happy:/home/debian# apachectl -V Server version: Apache/2.4.25 (Debian) Server built: 2017-09-19T18:58:57 Server's Module Magic Number: 20120211:68 Server loaded: APR 1.5.2, APR-UTIL 1.5.4 Compiled using: APR 1.5.2, APR-UTIL 1.5.4 Architecture: 64-bit Server MPM: event threaded: yes (fixed thread count) forked: yes (variable process count)
Y vemos que wordpress sigue funcionando:
Tarea 3 (1 punto)(Obligatorio): Cambia la configuración anterior para que FPM-PHP escuche en un socket TCP.
Para que escuche en un socket TCP hay que cambiar la línea de listen en /etc/php/7.0/fpm/pool.d/www.conf por:
listen = 127.0.0.1:9000
En el virtual host de worpress añadimos:
<FilesMatch "\.php$"> SetHandler "proxy:fcgi://127.0.0.1:9000" </FilesMatch>
Reiniciamos apache y ya funciona el wordpress de nuevo:
Para estas dos tareas voy a usar una maquina llamada happy que será Ubunut 16.04
Tarea 4 (1 punto)(Obligatorio): Documenta la instalación y configuración de FPM-PHP y nginx (escuchando en un socket UNIX) con el módulo de multiprocesamiento event. Muestra wordpress funcionando con FPM-PHP. Realiza una comprobación de que, efectivamente, se está usando FPM-PHP.
INSTALACIÓN SERVIDOR LEMP
sudo apt-get install nginx sudo apt-get install mysql-server mysqld --initialize sudo mysql_secure_installation sudo apt-get install php7.0-fpm php7.0-mysql
En el fichero /etc/php/7.0/fpm/php.ini modificamos la línea de cgi.fix_pathinfo para que quede:
cgi.fix_pathinfo=0
Para aplicar el cambio reiniciamos php7.0-fpm
sudo systemctl restart php7.0-fpm
En el fichero /etc/nginx/sites-available/default indicamos la configuración de php
# Default server configuration # server { listen 80 default_server; listen [::]:80 default_server; root /var/www/html/; index index.php index.html index.htm index.nginx-debian.html; #server_name 172.22.200.103; location / { try_files $uri $uri/ =404; } error_page 404 /404.html; error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass unix:/var/run/php/php7.0-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }
Creamos un info.php
<?php phpinfo(); ?>
INSTALACION DE WORDPRESS CON NGINX
Primero hay que crear usuario mysql
mysql -u root -p
CREATE DATABASE wordpress; CREATE USER wordpressuser@localhost IDENTIFIED BY 'password'; GRANT ALL PRIVILEGES ON wordpress.* TO wordpressuser@localhost; FLUSH PRIVILEGES;
Lo siguiente es descargar wordpress
cd ~ wget http://wordpress.org/latest.tar.gz tar xzvf latest.tar.gz sudo apt-get update sudo apt install php7.0-gd php-ssh2
Ahora hay que configurar wordpress
cd ~/wordpress cp wp-config-sample.php wp-config.php
curl -s https://api.wordpress.org/secret-key/1.1/salt/
La salida del comando:
define('AUTH_KEY', '.fT!{9x-bjDKmst)~DnCUcs`E{v>3pMsYfp[d8qJwYC!Ptg!^}l^A3H+i3o.[!{B'); define('SECURE_AUTH_KEY', '<*us+&mZfV|^Pu10utYbzO&5L#bmd<wRuYl92+qahjZD6c2Q)#7< IeX1{-=J5.['); define('LOGGED_IN_KEY', '%-C`X@PH99c`51p=?jsJB#[b9%FY5a{>Fj ]|_7;B}$UGa5])9#I|E8B8+2y+f1N'); define('NONCE_KEY', 'FE<au)]*yf]<QLWieXFI!(m?j-NCzBo:,nXiN2F[V^S*A!]&BgZYWyNi|3mC*f*$'); define('AUTH_SALT', 'CRvUO/)-!;w7oKfkRVH}z:odzpGn:NG#-fBx>p76nr(H}J}}Co{<~px-Y|Wl_FZy'); define('SECURE_AUTH_SALT', '$sl=FT0rU-I,|_Et+eX!$5DUUb%H@gBiL1FTAe$(tdIHp%cLH-/i8,&RD;HC![_m'); define('LOGGED_IN_SALT', 'u;x%gM%lv;8&1}.{ztc*qcaQHobn/0F42TsxE_hIbJL9~Gn2#|-S:Sdm,l[5;eX<'); define('NONCE_SALT', '?->@du/OcpqqHzSD>h#{%JZp+m/<r$=i+H-v/&ueS2u:k ~-}MnEp 2/G8tY Z&E');
la ponemos en el fichero wp-config.php junto con los siguientes parámetros de mysql
define('DB_NAME', 'wordpress'); define('DB_USER', 'wordpressuser'); define('DB_PASSWORD', 'password');
Lo siguiente será copiar los ficheros a document root con rsync y darle el propietario www-data:www-data
sudo mkdir -p /var/www/html sudo rsync -avP ~/wordpress/ /var/www/html/ sudo chown -R www-data:www-data /var/www/html/*
Creamos la carpeta uploads y le damos el propietario www-data:www-data
cd /var/www/html/ mkdir wp-content/uploads sudo chown -R :www-data /var/www/html/wp-content/uploads
Y ya está nuestro wordpress instalado con nginx.
Tarea 5 (1 punto)(Obligatorio): Cambia la configuración anterior para que FPM-PHP escuche en un socket TCP.
Para que escuche hay que modificar dos ficheros:
/etc/nginx/sites-available/default, al que hay que cambiarle la líena de fastcgi_pass por:
fastcgi_pass 127.0.0.1:9000;
y /etc/php/7.0/fpm/pool.d/www.conf, al que hay que cambiarle la línea de listen por:
listen = 127.0.0.1:9000
Reiniciamos nginx y php7.70-fpm y ya está operativo
sudo service nginx restart sudo service php7.0-fpm restart
Estudio de rendimiento
Ahora utilizando el script benchmark.py, realiza las pruebas de rendiemento para cada una de las configuraciones anteriores:
Módulo php5-apache2
FPM-PHP + apache2 (escuchando en un socket UNIX o en un socket TCP)
FPM-PHP + nginx (escuchando en un socket UNIX o en un socket TCP)
Tarea 6 (5 puntos)(Obligatorio): Entrega la configuración del script de pruebas para cada una de las configuraciones. Entrega los datos obtenidos y la gráfica que has generado.
Las modificaciones para apache son:
CONN =[1,10,25,50,75,100] TITULO="apache" DURATION="10" IP="localhost" URLS=["index.php","?p=1","?p=2"] SERVERS=["apache", "php7.0-fpm"]
Las modificaciones para nginx son:
CONN =[1,10,25,50,75,100] TITULO="nginx" DURATION="10" IP="172.22.200.103" URLS=["index.php","?p=1","?p=2"] SERVERS=["nginx", "php7.0-fpm"]
Los datos obtenidos son:
1 | 10 | 25 | 50 | 75 | 100 | |
nginx unix | 30,36 | 30,25333333 | 28,26333333 | 27,02 | 347,0766667 | 2135,006667 |
nginx tcp | 29,27 | 29,74333333 | 29,60333333 | 27,25666667 | 25,14666667 | 24,36333333 |
apache unix | 30,15666667 | 26,7 | 26,79333333 | 25,12666667 | 23,39333333 | 21,15333333 |
apache tcp | 29,00666667 | 27,63 | 25,87333333 | 24,94666667 | 23,15 | 21,50666667 |
Y la gráfica queda:
Aumento de rendimiento
Tarea 7 (2 puntos)(Obligatorio): Añade a la configuración ** ganadora del punto anterior** memcached. Documenta la instalación y configuración memcached. Recuerda que para que WordPress utilice memcached le tenemos que instalar un plugin. Muestra las estadísticas de memcached después de acceder varias veces a wordpress para comprobar que esa funcionando.
INSTALACIÓN
apt install memcached php-memcached systemctl restart memcached php7.0-fpm
En la instalación se genera un usuario llamada memcache que hay que añadir al grupo www-data:
usermod -g www-data memcache
PLUGINS
Para instalar los plugins (MemcacheD Is Your Friend y W3 Total Cache) lo podemos hacer desde la misma web:
–
Para que W3 Total Cache funcione, hay que copiar el fichero de configuración de nginx a /var/www/html/ y darle el propietario correcto
cp /etc/nginx/nginx.conf /var/www/html/nginx.conf cd /var/www/html/ chown www-data:www-data nginx.conf
Y ya tenemos nuestro wordpress con nginx y memcached funcionando.
Tarea 8 (3 puntos)(Obligatorio): Configura un proxy inverso – caché Varnish escuchando en el puerto 80 y que se comunica con el servidor web por el puerto 8080. Entrega y muestra una comprobación de que varnish está funcionando con la nueva configuración.
apt install varnish
Ahora tenemos que modificar el fichero /etc/default/varnish y añadirle:
DAEMON_OPTS="-a :80 \ -T localhost:6082 \ -f /etc/varnish/default.vcl \ -S /etc/varnish/secret \ -s malloc,256m"
Para aplicar los cambios reiniciamos varnish
systemctl restart nginx varnish
Y vemos que está activo
netstat -putan | grep varnish tcp 0 0 0.0.0.0:6081 0.0.0.0:* LISTEN 1206/varnishd tcp 0 0 127.0.0.1:6082 0.0.0.0:* LISTEN 1206/varnishd tcp6 0 0 :::6081 :::* LISTEN 1206/varnishd
Para indicarle que escuche también por el puerto 80, modificamos la unidad de systemd que está en /lib/systemd/system/varnish.service
[Unit] Description=Varnish HTTP accelerator Documentation=https://www.varnish-cache.org/docs/4.1/ man:varnishd [Service] Type=simple LimitNOFILE=131072 LimitMEMLOCK=82000 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 ExecReload=/usr/share/varnish/reload-vcl ProtectSystem=full ProtectHome=true PrivateTmp=true PrivateDevices=true [Install] WantedBy=multi-user.target
Reiniciamos para aplicar los cambios:
systemctl daemon-reload systemctl restart nginx varnish
En el fichero de configuración de wordpress ponemos la siguiente línea para que escuche por el puerto 8080
listen 127.0.0.1:8080 default_server;
Si ejecutamos varnishstat vemos algunos datos interesantes del proceso
Uptime mgt: 0+00:02:35 Hitrate n: 6 6 6 Uptime child: 0+00:02:35 avg(n): 0.0000 0.0000 0.0000 NAME CURRENT CHANGE AVERAGE AVG_10 AVG_100 AVG_1000 MAIN.uptime 0+00:02:35 MAIN.pools 2 0.00 . 2.00 2.00 2.00 MAIN.threads 200 0.00 . 200.00 200.00 200.00 MAIN.threads_created 200 0.00 1.00 0.00 0.00 0.00 MAIN.n_backend 1 0.00 . 1.00 1.00 1.00 MAIN.n_vcl 1 0.00 . 0.00 0.00 0.00 MAIN.bans 1 0.00 . 1.00 1.00 1.00 MGT.uptime 0+00:02:35 SMA.s0.g_space 256.00M 0.00 . 256.00M 256.00M 256.00M
Estudio de rendimiento
A continuacion hacemos el estudio de rendimiento para las siguientes configuraciones:
Configuración ganadora
Configuración ganadora + memcached
Configuración ganadora + varnish
Tarea 9 (5 puntos): Entrega la configuración del script de pruebas para cada una de las configuraciones. Entrega los datos obtenidos y la gráfica que has generado.
Gráfica ganadora:
Datos:
30,36 30,25333333 28,26333333 27,02 347,0766667 2135,006667
Gráfica ganadora + memcached:
Modificación de benchmark.py
CONN =[1,10,25,50,75,100] TITULO="nginx" DURATION="10" IP="172.22.200.103" URLS=["index.php","?p=1","?p=2"] SERVERS=["nginx", "php7.0-fpm", "memcached"]
Datos:
"24,75" "23,48" "22,73" "21,1366666667" "585,746666667" "2892,35"
Gráfica ganadora + varnish:
Modificación de benchmark.py
CONN =[1,10,25,50,75,100] TITULO="nginx" DURATION="10" IP="127.0.0.1:80" URLS=["index.php","?p=1","?p=2"] SERVERS=["nginx", "php7.0-fpm","varnish"]
Datos:
"24,9033333333" "22,19" "21,91" "19,2933333333" "669,43" "2855,69"