Ejemplo de mala cache en una aplicación web
Una de las buenas prácticas de cualquier aplicación web es cachear los datos para devolver las peticiones lo más rápidamente posible. El problema es que después la gente entiende mal la cache y hace burradas.
Un ejemplo de malas prácticas para generar una cache es insertar un código similar al siguiente en cada petición web:
<?php
$ch = curl_init();
$curl_options = array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_USERAGENT => 'lammer_cache');
curl_setopt_array($ch, $curl_options);
foreach( $zonas as $zona )
{
if( $zona['id'] == 100 )
curl_setopt($ch, CURLOPT_URL, "$host/?nocache");
else
curl_setopt($ch, CURLOPT_URL, "$host/{$zona['slug']}/?nocache");
$salida = curl_exec($ch);
$archivo = fopen(dirname(__FILE__)."/lammer_cache/{$zona['slug']}.html", 'w');
fwrite($archivo, $salida);
fclose($archivo);
}
curl_close($ch);
?>
Lo que hace es, según unas condiciones de refresco que he recortado, realizar una petición mediante curl a si mismo para un conjunto de datos y guardar el HTML resultante. Este código tiene varios problemas:
- Este proceso es lento, por lo que el usuario que al realizar la petición al site tenga que hacer al refresco va a tardar mucho a devolverle el resultado, por lo que lo más probable es que el navegador le de un timeout.
- Es propenso a dejar peticiones colgadas en el servidor web o a ejecutarse varias veces. En este punto hablo experimentalmente, porque no me he mirado bien el código, pero supongo que por un mal chequeo de las condiciones puede llegar a ejecutarse, realizar la petición a si mismo y esta misma querer volver a generarse generando más peticiones a si mismo. Esto, en principio, sería fácilmente corregible.
- No comprueba el resultado de la petición, por ejemplo si la petición devuelve un 503, este código cachearía el HTML del error 503 y lo mostraría como HTML resultante válido
Una cache bien entendida depende de los retos de cada aplicación web, pero un código así es horrible ya que esto mismo se puede hacer simplemente usando un proxy inverso, por ejemplo el squid, sin tocar una sola línea de código y mucho más robusto y eficiente.
Para cachear datos por algún ID, como en el ejemplo, por ID de zona, podemos usar una tabla de hash en memoria como es memcached o para búsquedas usar un motor más eficiente como puede ser Sphinx, Lucene o SOLR en lugar de LIKE o índices FULLTEXT de MySQL. Todo depende del caso en concreto, pero generar los HTML en ficheros con código PHP me parece una chapuza y con más razón si encima esta mal programado como en este caso.
Relacionados
Imprimir
Deja un comentario: