CGI & FastCGI

CGI

Cuando tenemos un servidor HTTP, normalmente querrémos crear contenido dinámico mediante código con programas escritos por ejemplo en PHP. Este tipo de lenguajes suelen ser lenguajes de scripting interpretados para favorecer la portabilidad, lo que significa que en cada petición HTTP que pida una página de contenido dinámico, se ejecutará un script para generar un documento HTML.

Ahora bien, estos scripts no están integrados dentro del servidor HTTP, son programas ajenos a este, así que se tienen que comunicar de alguna manera.

Aquí es donde entra en juego el protocolo CGI (Common Gateway Interface) que es un protocolo de comunicaciones estandarizado entre el servidor HTTP y los programas externos que se pueden ejecutar desde una consola de comandos (como PHP).

El protocolo CGI indica que por cada petición se crea un proceso dentro del SO que ejecuta el script al cual se le pasa información por variables de entorno (Tales como QUERY_STRING, REQUEST_METHOD, etc); y da como respuesta al servidor HTTP (y por ende al cliente) un objeto de tipo MIME que debe indicar el tipo de objeto entregado indicándolo en la varibale «CONTENT_TYPE: tipo/subtipo» (habitualmente «text/html»).

Estos scripts que se ejecutan de manera externa al servidor HTTP y que se comunican a través del protocolo CGI se denominan «scripts CGI».

FastCGI

La creación y destrucción de procesos que se produce cada vez que un cliente realiza una petición HTTP a un documento de contenido dinámico, genera mucha sobrecarga del sistema cuando hay una significativa cantidad de usuarios que acceden al sitio web; es por ello que se creó una versión del protocolo CGI llamado FastCGI para optimizar el uso de los recursos del sistema, que consiste básicamente en tener un servicio que tiene un conjunto de procesos que se ejecutan de forma persistente (llamado «process pool») para evitar la creación y destrucción constante de los mismos. Cada uno de estos procesos están constantemente esperando nuevas solicitudes para ejecutar código.

El servidor HTTP se comunica con el servicio del FastCGI y este deriva la petición a uno de sus procesos persistentes para que cree el documento de contenido dinámico.

Por tanto, el protocolo FastCGI solo puede ser implementado en lenguajes que tengan soporte para sockets.

PHP en FastCGI

Para optimizar aún más los tiempos de respuesta, PHP suele publicar en sus compilaciones la versión NTS (non-thread safe) del intérprete. Esta versión del intérprete omite ciertas rutinas de comprobación que se realizan en la versión de threads seguros, reduciendo así los tiempos de ejecución. Al usar CGI o FastCGI, cada hilo se ejecuta de manera aislada y es por ello que no es necesario realizar las rutinas de comprobación para mantener los hilos seguros.

Por otro lado, PHP tiene actualmente 3 ejecutables en su distribución:

  • php.exe = PHP CLI (Command Line Interpreter/Interface). Ejecuta un script PHP desde la consola de comandos con buffer de salida (omitiendo cabeceras HTTP, cookies, etc).
  • php-win.exe = Igual que PHP CLI pero sin salida (solo ejecuta el script PHP, útil por ejemplo para poblar datos de una BD).
  • php-cgi.exe = ejecuta los scripts de PHP con compatibilidad de comunicación con el protocolo CGI.

Para usar PHP con CGI o FastCGI debemos usar el ejecutable «php-cgi.exe» cuando configuremos el servicio FastCGI, pues este ya viene preparado para realizar comunicación estándar con el protocolo CGI.

Usar CGI provocará que se ignoren las directrices encontradas en archivos de configuración del servidor (como por ejemplo «.htaccess») ya que el servidor no interviene en la ejecución del script CGI y éste no entiende qué es el archivo «.htaccess». En php se puede optar por usar directrices específicas bajo la cabecera [PATH=»directorio»] ó [HOST=»www.example.com»] en el archivo de configuración global «php.ini» para que apliquen dentro de ese directorio o dominio. También se puede optar por usar archivos de configuración locales (archivos que deben nombrarse por defecto «.user.ini», se puede modificar en la variable «user_ini.filename» de php.ini).

NOTA: Desde archivos de configuración local no se pueden modificar aquellos atributos de php.ini que tengan como atributo «changeable» el valor PHP_INI_PERDIR o PHP_INI_USER (puedes ver la lista de atributos que tienen esta característica aquí).

Módulos de intérpretes embebidos

Algunos servidores HTTP no tienen implementado el protocolo FastCGI o prefieren no utilizarlo, así que usan módulos de comunicación propios con los scripts CGI, esto es, una interfaz de comunicación específica para que el propio script interactue con el servidor HTTP de manera integrada (el script se ejecuta dentro del servidor HTTP en lugar de hacerlo como un programa externo). A estos módulos se les conoce como «intérpretes embebidos».

Apache por ejemplo hace uso de estos módulos para comunicarse con scripts PHP y Perl (llamados mod_php y mod_perl respectivamente).

La forma de funcionar de estos módulos es integrar el intérprete de PHP, Perl, etc dentro del hilo de ejecución de la petición HTTP que se está sirviendo, provocando tiempos de respuesta menores (pero provocan un mayor uso de memoria pues la petición de un documento estático provocará que se cargue también el intérprete dentro del hilo de ejecución).

Una desventaja de usar módulos embebidos es que la ejecución del script CGI no está aislada (se ejecuta dentro del servidor HTTP) y un error en la interpretación de un fichero podría llegar a afectar al resto de ficheros del dominio donde se alojan.

Otros métodos de optimización del CGI

Otras alternativas de optimización del protocolo CGI es usar lenguajes precompilados (como C o C++) para evitar que se interprete el código fuente desde cero.


Créditos de fuentes externas:

Iconos:

  • PC by art shop from the Noun Project
  • Server by Chanut is Industries from the Noun Project
  • Gears by Gregor Cresnar from the Noun Project

Deja un comentario