¿ Lentitud en IIS con FastCGI y PHP ?

Mediante FastCGI para IIS podemos tener soporte para PHP sobre el servidor de Microsoft para Windows (IIS).

No es la mejor opción para servir aplicaciones en PHP pero, cuando los requisitos de servidor son estos, no queda otro remedio.

Estos días he estado realmente ocupado en el desarrollo de de una plataforma de eCommerce sobre esta plataforma. Para mejorar el rendimiento se utiliza membase (algo más que un servidor de Memcache para windows), así como un sistema de datos híbrido: MySQL y MongoDB, Haanga como sistema de plantillas y como buscador una modificación del Zend_Search_Lucene.

Todo parecía ir bien hasta que empezamos a ver una extraña lentitud en algunas peticiones, por lo que, se revisaron las consultas, dando la más pesada (en el MySQL slow query log) 2 segundo, algo por debajo de los 20 segundos que tardaban algunas páginas, sin complejidad aparente.

No había una carga de red grande, ni un número de peticiones considerable simultáneas, pero había momentos de extrema lentitud.

No encontrando el origen, y comprobado que en el servidor de desarrollo y pre-producción, con los mismos datos, no se producían esos problemas, acabamos añadiendo, en producción, diferentes error_log() en zonas concretas para afinar el origen del problema.

Cada vez que se veían los logs, observábamos pautas muy diferentes, los tiempos eran aparentemente aleatorios, unas veces eran antes de una consulta sencilla, otras en el momento de renderizar la plantilla, otras a la hora de buscar un valor en la caché … aparecían en cualquier sitio y en cualquier momento, haciendo la web completamente inoperativa.

Una vez se descartaron los diferentes orígenes: MongoDB, Consultas SQL, Caché en memoria … me fijé en que los logs eran erráticos, no los veía como en un Unix con un tail -f, sino que los veía a saltos.

¿ Y si este era el problema ?

Efectivamente, mi suposición fue tan simple como: Con FastCGI se lanzan multiples procesos php5-cgi.exe que van recibiendo el código php y lo procesan, y si algo tiene Windows con los ficheros, especialmente NTFS, es una gran dificultad para poder añadir información al final de un fichero desde múltiples procesos. En este caso los simples error_log() que se lanzaban, provocaban bloqueos entre los distintos procesos FastCGI.

Sólo eliminando todos los error_log y grabaciones similares a archivos, y pasándolo a base de datos y todo volvió a la normalidad, velocidad correcta.

En resumen: Si no queda otra que utilizar un IIS con FastCGI + PHP, bajo ningún concepto utilizar ningún fichero para logs, o funciones como error_log() (que hacen lo mismo) ya que nos encontraremos con bloqueos de los diferentes procesos a la hora de acceder a ese archivo y añadir la información. En teoría grabar un log, básico, en Base de datos es menos eficiente que hacerlo en texto puro en un archivo, pero en Windows no tendremos más remedio que resolverlo así.

Nota: Desconozco si apache (mod_php) en windows tiene este problema.

He buscado en Internet alguna información sobre este problema, pero no he encontrado absolutamente nada.