Problema
¿Por qué las imágenes caducan inmediatamente en un explorador?
Solución
CDN Caching y TTL (Time-to-Live)
Con Adobe Scene7, puede establecer diferentes caducidades para imágenes específicas. Por ejemplo, la imagen predeterminada que se muestra cuando no se encuentra una imagen, se configura automáticamente para que tenga un tiempo de caducidad más corto.
Time-to-Live (TTL) es un mecanismo para limitar la vida útil de los datos en una red. Nuestros proveedores de la Red de Entrega de Contenido (CDN) ofrecen esta configuración. Una vez transcurrido el tiempo de espera, una petición GET de un objeto activa una petición IMS (If-Modified-Since) al origen Scene7. Si nuestro proveedor de CDN recibe una respuesta 304 (No Modificada) de nuestros servidores de origen, el objeto se actualiza, junto con un encabezado Expires actualizado, si ha cambiado.
Hace varios años, teníamos un TTL de diez horas, que era autoritativo, y el encabezado Expires no tuvo ningún impacto en nuestro caching CDN. Esta configuración se modificó para que cuando un objeto expiraba con el CDN TTL o basado en el encabezado “Expires:”, el objeto se actualizara en la siguiente petición “GET”. Este proceso también actualizó las cabeceras. En resumen, ahora anulamos el TTL de la CDN si el tiempo de expiración del encabezado es más corto que el TTL configurado.
Esta condición se aplica cuando el objeto está “en caché” en Akamai. Cuando Akamai realiza una solicitud de if-modified-since (IMS) al origen, no tiene ningún tráfico de alto impacto, porque solo se intercambian encabezados HTTP. El objeto no se vuelve a descargar. Nuestra CDN solo comprueba si el objeto no ha cambiado, y actualiza el TTL de ese objeto en la caché.
El impacto de este cambio en la configuración de la CDN fue que ahora hay más solicitudes IMS frecuentes hechas a los servidores de origen para contenido con un tiempo de caducidad bajo.
La configuración de la CDN cambia, ¿por qué una imagen expiraría inmediatamente en un navegador?
Ejemplo:
Response Headers:
Content-Type[image/jpeg]
Last-Modified[Wed, 20 Jun 2007 21:29:20 GMT]
Etag["0b3a49e639331555ba959a9f1e332c2f"]
Expires[Mon, 13 Aug 2007 02:00:28 GMT]
Date[Mon, 13 Aug 2007 02:00:28 GMT]
Connection[keep-alive]
Hace varios años, encontramos que este objeto estaba almacenado en la caché con un encabezado Expires en el pasado:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Expires: Mon, 13 Aug 2007 16:53:16 GMT
Last-Modified: Thu, 19 Jul 2007 21:42:18 GMT
ETag: "ebb5a6db6c4e78a15db53a29d9d0b9d2"
Content-Type: image/jpeg
Content-Length: 14141
Date: Mon, 13 Aug 2007 06:53:15 GMT
Age: 0
X-Akamai-Purge-Seq-Num: 1336350
Connection: keep-alive
Con nuestros ajustes de configuración anteriores de la Red de Entrega de Contenido (CDN), este comportamiento fue el que se diseñó. Tener un objeto almacenado en caché con un encabezado Expires en el pasado resultó en un encabezado downstream expira de “Ahora” La fecha de “Última modificación” no había cambiado. Como resultado, una respuesta HTTP 304 desde el origen de una petición if-modified-since (IMS) no actualizaba las cabeceras de los objetos cacheados con Akamai. Cuando un objeto se almacenaba en caché y expiraba, nuestro proveedor de CDN siempre enviaba una solicitud de “if-modified-since” (IMS) al origen. Debido a que la fecha de “Última modificación” es la misma, nuestro proveedor de CDN recibió una respuesta HTTP 304. Luego, el caché de objetos Time-To-Live (TTL) se actualizó a diez horas basado en la configuración, pero el objeto y las cabeceras permanecieron sin cambios.
En ese momento, actualizamos los metadatos de la CDN para controlar la actualización de los encabezados en caché.
La etiqueta que nos permitió cambiar las cabeceras de la capacidad de caché en una respuesta 304 del servidor de origen fue:
<cache:header-update.allow>con</cache:header-update.allow>
Por defecto, nuestro proveedor de CDN no actualiza las cabeceras de un objeto almacenado en caché con las cabeceras recibidas en una respuesta 304. Como resultado, una vez transcurrido el tiempo de expiración, el objeto permanecerá viejo en la caché de la CDN (y para cualquier usuario final) hasta que el origen devuelva una respuesta 200 con un nuevo objeto. Una vez alcanzado el tiempo de expiración, si el origen respondía con un 304, el servidor CDN continuaría revalidando con el origen en cada solicitud. También serviría al cliente-navegador un objeto que ya estaba caducado. Esto causó que el explorador tuviera que revalidar en la siguiente carga.
Cuando activamos la etiqueta cache:header-update.allow, que indicaba a los servidores de la CDN que actualizaran las cabeceras directivas de la caché en la respuesta en caché si eran diferentes en la respuesta 304. Los encabezados que se consideran cabeceras “directiva de caché” para esta característica son: Expires, Cache-Control, Edge-Control (e implícitamente Surrogate-Control).
También existe un control relacionado sobre la frecuencia con la que los encabezados se actualizan en la caché. Este control existe para evitar una situación en la que el servidor CDN deba escribir encabezados en la caché en cada respuesta porque el servidor de origen está configurando un nuevo encabezado Expires con cada respuesta (no es el caso de las respuestas de Adobe Scene7). La configuración predeterminada para la frecuencia de actualización de los encabezados es de un minuto, pero este valor se puede cambiar con la etiqueta de metadatos:
<cache:header-update.max-frequency>1m</cache:header-update.max-frequency>
Cuando se alcanza TTL, el objeto se considera rancio en EdgeServers. Una solicitud IMS siempre se envía al origen para comprobar la hora de la última modificación de ese mismo objeto.
El cambio de metadatos que hicimos permite refrescar los encabezados junto con la respuesta 304 desde el origen. Este cambio no resultó en una descarga completa de ese mismo objeto si no fue modificado.
La solicitud if-modified-since a los servidores de origen solo se realiza cuando el contenido está obsoleto. Es decir, después de que el TTL caduque, los encabezados no se actualizan con tanta frecuencia.