Cómo configurar Apache HTTP con MPM Event y PHP-FPM en FreeBSD 12.0

El autor seleccionó el Open Internet/Free Speech Fund para recibir una donación como parte del programa Write for DOnations.

Introducción

El servidor web Apache HTTP ha evolucionado a lo largo de los años para trabajar en diferentes entornos y resolver diferentes necesidades. Un problema importante que tiene que resolver Apache HTTP, como cualquier servidor web, es cómo manejar diferentes procesos para servir una petición del protocolo http. Esto implica abrir un socket, procesar la petición, mantener la conexión abierta durante un periodo determinado, manejar los nuevos eventos que se produzcan a través de esa conexión y devolver el contenido producido por un programa hecho en un lenguaje concreto (como PHP, Perl o Python). Estas tareas son realizadas y controladas por un Módulo de Multiprocesamiento (MPM).

Apache HTTP viene con tres MPM diferentes:

  • Pre-fork: Se crea un nuevo proceso para cada conexión entrante que llega al servidor. Cada proceso está aislado de los demás, por lo que no se comparte memoria entre ellos, aunque estén realizando llamadas idénticas en algún momento de su ejecución. Esta es una forma segura de ejecutar aplicaciones enlazadas a librerías que no soportan threading -típicamente aplicaciones o librerías más antiguas.
  • Worker: Un proceso padre es responsable de lanzar un conjunto de procesos hijos, algunos de los cuales están a la escucha de nuevas conexiones entrantes, y otros están sirviendo el contenido solicitado. Cada proceso tiene un hilo (un solo hilo puede manejar una conexión), por lo que un proceso puede manejar varias solicitudes simultáneamente. Este método de tratamiento de las conexiones favorece una mejor utilización de los recursos, al tiempo que mantiene la estabilidad. Esto es el resultado del pool de procesos disponibles, que a menudo tiene hilos libres disponibles para servir inmediatamente nuevas conexiones.
  • Evento: Basado en worker, este MPM va un paso más allá optimizando cómo el proceso padre programa las tareas a los procesos hijos y los hilos asociados a estos. Una conexión permanece abierta durante 5 segundos por defecto y se cierra si no se produce un nuevo evento; este es el valor por defecto de la directiva keep-alive, que conserva el hilo asociado a ella. El MPM de eventos permite que el proceso gestione los hilos de forma que algunos queden libres para gestionar nuevas conexiones entrantes mientras que otros se mantienen vinculados a las conexiones vivas. Permitir la redistribución de las tareas asignadas a los hilos hará que se utilicen mejor los recursos y el rendimiento.

El módulo MPM Event es un módulo de multiprocesamiento rápido disponible en el servidor web Apache HTTP.

PHP-FPM es el gestor de procesos FastCGI para PHP. El protocolo FastCGI está basado en el Common Gateway Interface (CGI), un protocolo que se sitúa entre las aplicaciones y los servidores web como Apache HTTP. Esto permite a los desarrolladores escribir aplicaciones por separado del comportamiento de los servidores web. Los programas ejecutan sus procesos de forma independiente y pasan su producto al servidor web a través de este protocolo. Cada nueva conexión que necesite ser procesada por una aplicación creará un nuevo proceso.

Al combinar el Evento MPM en Apache HTTP con el Gestor de Procesos PHP FastCGI (PHP-FPM) un sitio web puede cargar más rápido y manejar más conexiones concurrentes mientras utiliza menos recursos.

En este tutorial mejorarás el rendimiento de la pila FAMP cambiando el módulo de multiprocesamiento por defecto de prefork a evento y utilizando el gestor de procesos PHP-FPM para manejar el código PHP en lugar del clásico mod_php de Apache HTTP.

Requisitos previos

Antes de empezar esta guía necesitarás lo siguiente:

  • Un servidor FreeBSD 12.0 configurado siguiendo esta guía.
  • La pila FAMP instalada en tu servidor siguiendo este tutorial.
  • Acceso a un usuario con privilegios de root (o permitido mediante el uso de sudo) para poder realizar cambios de configuración.

Paso 1 – Cambiar el módulo de multiprocesamiento

Empezarás buscando la directiva pre-fork en el archivo httpd.conf. Este es el archivo de configuración principal para Apache HTTP en el que puedes habilitar y deshabilitar módulos. Puedes editar y establecer directivas como el puerto de escucha en el que Apache HTTP servirá el contenido o la ubicación del contenido a mostrar en este archivo.

Para hacer estos cambios, utilizarás el programa nl, number line, con la bandera -ba para contar y numerar las líneas para que nada se desajuste en una etapa posterior. Combinado con grep este comando contará primero todas las líneas del fichero especificado en la ruta, y una vez terminado, buscará la cadena de caracteres que se busca.

Ejecuta el siguiente comando para que el programa nl procese y numere las líneas de httpd.conf. Luego, grepprocesará la salida buscando la cadena de caracteres dada 'mod_mpm_prefork':

  • nl -ba /usr/local/etc/apache24/httpd.conf | grep 'mod_mpm_prefork'

Como salida verás algo similar a:

Output
67 LoadModule mpm_prefork_module libexec/apache24/mod_mpm_prefork.so

Editemos la línea 67 con tu editor de texto. En este tutorial, usará vi, que es el editor por defecto en FreeBSD:

  • sudo vi +67 /usr/local/etc/apache24/httpd.conf

Aplique un símbolo # al principio de la línea para que esta línea sea comentada, así:

/usr/local/etc/apache24/httpd.conf
...# LoadModule mpm_prefork_module libexec/apache24/mod_mpm_prefork.so...

Al añadir el símbolo # ha desactivado el módulo MPM pre-fork.

Ahora encontrarás la directiva de eventos en el mismo archivo httpd.conf.

  • nl -ba /usr/local/etc/apache24/httpd.conf | grep mpm_event

Verás una salida similar a la siguiente:

Output
...66 #LoadModule mpm_event_module libexec/apache24/mod_mpm_event.so...

Ahora eliminarás el símbolo # en la línea 66 para habilitar el MPM de eventos:

  • sudo vi +66 /usr/local/etc/apache24/httpd.conf

La directiva se leerá ahora así:

/usr/local/etc/apache24/httpd.conf
...LoadModule mpm_event_module libexec/apache24/mod_mpm_event.so...

Ahora que ha cambiado la configuración del prefork de MPM a evento, puede eliminar el paquete mod_php73que conecta el procesador PHP a Apache HTTP, ya que ya no es necesario e interferirá si permanece en el sistema:

  • sudo pkg remove -y mod_php73

Asegúrese de que la configuración es correcta ejecutando el siguiente comando para probar:

  • sudo apachectl configtest

Si ve Syntax OK en su salida, puede reiniciar el servidor Apache HTTP:

  • sudo apachectl restart

Nota: Si hay otras conexiones HTTP en ejecución en su servidor se recomienda un reinicio graceful en lugar de un reinicio regular. Esto asegurará que los usuarios no sean expulsados, perdiendo su conexión:

  • sudo apachectl graceful

Has cambiado el MPM de prefork a evento y has eliminado el módulo mod_php73 de conexión PHP a Apache HTTP. En el siguiente paso instalará el módulo PHP-FPM y configurará Apache HTTP para que pueda comunicarse con PHP más rápidamente.

Paso 2 – Configurar Apache HTTP para usar el gestor de procesos FastCGI

FreeBSD tiene varias versiones de PHP soportadas que puede instalar a través del gestor de paquetes. En FreeBSD se compilan diferentes binarios de las distintas versiones disponibles en lugar de utilizar uno solo como la mayoría de las distribuciones GNU/Linux ofrecen en sus repositorios por defecto. Para seguir las mejores prácticas usará la versión soportada, que puede comprobar en la página de versiones soportadas de PHP.

En este paso añadirá PHP-FPM como un servicio en ejecución para que se inicie en el arranque. También configurará Apache HTTP para que funcione con PHP añadiendo una configuración dedicada para el módulo así como habilitando algunos módulos más en httpd.conf.

Primero añadirá 'php_fpm_enable=YES' al fichero /etc/rc.conf para que el servicio PHP-FPM pueda iniciarse. Lo harás usando el comando sysrc:

  • sudo sysrc php_fpm_enable="YES"

Ahora añadirás el módulo php-fpm en el directorio de módulos de Apache, para que esté configurado para ser usado por Apache HTTP. Crea el siguiente archivo para hacerlo:

  • sudo vi /usr/local/etc/apache24/modules.d/030_php-fpm.conf

Añade lo siguiente en 030_php-fpm.conf:

/usr/local/etc/apache24/modules.d/030_php-fpm.conf
<IfModule proxy_fcgi_module> <IfModule dir_module> DirectoryIndex index.php </IfModule> <FilesMatch "\.(php|phtml|inc)$"> SetHandler "proxy:fcgi://127.0.0.1:9000" </FilesMatch></IfModule>

Esto establece que si el módulo 'proxy_fcgi' está habilitado así como el 'dir_module' entonces cualquier archivo procesado que coincida con las extensiones entre paréntesis debe ser manejado por el gestor de procesos FastCGI que se ejecuta en la máquina local a través del puerto 9000-como si la máquina local fuera un servidor proxy. Aquí es donde el módulo PHP-FPM y Apache HTTP se interconectan. Para lograr esto, activarás otros módulos durante este paso.

Para activar el módulo proxy, primero lo buscarás en el archivo httpd.conf:

  • nl -ba /usr/local/etc/apache24/httpd.conf | grep mod_proxy.so

Verás una salida similar a la siguiente:

Output
...129 #LoadModule proxy_module libexec/apache24/mod_proxy.so...

Descomentarás la línea eliminando el símbolo #:

  • sudo vi +129 /usr/local/etc/apache24/httpd.conf

La línea tendrá el siguiente aspecto una vez editada:

/usr/local/etc/apache24/httpd.conf
...LoadModule proxy_module libexec/apache24/mod_proxy.so...

Ahora puedes activar el módulo FastCGI. Busca el módulo con el siguiente comando:

  • nl -ba /usr/local/etc/apache24/httpd.conf | grep mod_proxy_fcgi.so

Verás algo parecido a lo siguiente:

Output
...133 #LoadModule proxy_fcgi_module libexec/apache24/mod_proxy_fcgi.so...

Ahora descomenta la línea 133 como ya has hecho con los otros módulos:

  • sudo vi +133 /usr/local/etc/apache24/httpd.conf

Dejarás la línea así:

/usr/local/etc/apache24/httpd.conf
...LoadModule proxy_fcgi_module libexec/apache24/mod_proxy_fcgi.so...

Una vez hecho esto arrancarás el servicio PHP-FPM:

  • sudo service php-fpm start

Y reiniciarás Apache para que cargue los últimos cambios de configuración que incorporan el módulo PHP:

  • sudo apachectl restart

Has instalado el módulo PHP-FPM, configurado Apache HTTP para que funcione con él, habilitado los módulos necesarios para que funcione el protocolo FastCGI y arrancado los servicios correspondientes.

Ahora que Apache tiene habilitado el módulo Event MPM y que PHP-FPM está presente y funcionando, es el momento de comprobar que todo funciona como es debido.

Paso 3 – Comprobación de la configuración

Para comprobar que los cambios de configuración se han aplicado, realizarás algunas pruebas. La primera comprobará qué módulo de multiprocesamiento está utilizando Apache HTTP. La segunda verificará que PHP está utilizando el gestor FPM.

Comprueba el servidor Apache HTTP ejecutando el siguiente comando:

  • sudo apachectl -M | grep 'mpm'

Tu salida será la siguiente:

Output
mpm_event_module (shared)

Puedes repetir lo mismo para el módulo proxy y FastCGI:

  • sudo apachectl -M | grep 'proxy'

La salida será la siguiente:

Output
proxy_module (shared)proxy_fcgi_module (shared)

Si desea ver la lista completa de los módulos, puede eliminar la segunda parte del comando después de -M.

Ahora es el momento de comprobar si PHP está utilizando el gestor de procesos FastCGI. Para ello escribirás un pequeñísimo script PHP que te mostrará toda la información relacionada con PHP.

Ejecuta el siguiente comando para escribir un archivo llamado como sigue:

  • sudo vi /usr/local/www/apache24/data/info.php

Añade el siguiente contenido en el archivo info.php:

info.php
<?php phpinfo(); ?>

Ahora visita la URL de tu servidor y añade info.php al final así: http://your_server_IP_address/info.php.

La entrada de la API del servidor será FPM/FastCGI.

PHP revisa la entrada de la API del servidor FPM/FastCGI

Recuerda borrar el archivo info.php después de esta comprobación para que no se revele públicamente ninguna información sobre el servidor.

  • sudo rm /usr/local/www/apache24/data/info.php

Ha comprobado el estado de funcionamiento del módulo MPM, los módulos que manejan el FastCGI, y el manejo del código PHP.

Conclusión

Leave a Reply