Problema
Por que as imagens expiram imediatamente em um navegador?
Solução
Cache de CDN e TTL (Time-To-Live)
Com o Adobe Scene7, você pode definir expirações diferentes para imagens específicas. Por exemplo, a imagem padrão que é exibida quando uma imagem não é encontrada é automaticamente configurada para ter um tempo de expiração mais curto.
Time-To-Live (TTL) é um mecanismo para limitar a vida útil dos dados em uma rede. Nossos provedores de Content Delivery Network (CDN) oferecem essa configuração. Quando o tempo de vida tiver sido alcançado, uma solicitação GET para um objeto acionará uma solicitação IMS (If-Modified-Since) para a origem Scene7. Se o nosso provedor de CDN receber uma resposta 304 (Not-Modified) de nossos servidores de origem, o objeto será atualizado, juntamente com um cabeçalho atualizado Expires, se ele tiver sido alterado.
Vários anos atrás, tínhamos um TTL de dez horas, que era autoritativo, e o cabeçalho Expires não teve impacto em nosso armazenamento de cache do CDN. Essa configuração foi alterada para que, quando um objeto expirasse com o CDN TTL ou com base no cabeçalho "Expires:", o objeto fosse atualizado na próxima solicitação "GET". Esse processo também atualizou os cabeçalhos. Em suma, agora substituímos o TTL do CDN se o tempo de cabeçalho Expires for menor que o TTL configurado.
A condição acima se aplica quando o objeto está "em cache" no Akamai. Quando o Akamai faz uma solicitação if-modified-since (IMS) para a origem, ele não possui nenhum tráfego de alto impacto, porque somente cabeçalhos HTTP são trocados. O objeto não é baixado novamente. Nosso CDN está apenas verificando se o objeto está inalterado e atualiza o TTL desse objeto no cache.
O impacto dessa alteração na configuração do CDN foi que agora há solicitações mais frequentes de IMS feitas aos servidores de origem para conteúdo com um tempo de expiração baixo.
Mudanças na configuração do CDN, por que uma imagem expiraria imediatamente em um navegador?
Exemplo:
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]
Vários anos atrás, descobrimos que este objeto foi armazenado em cache com um cabeçalho Expires no passado:
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
Com nossas configurações de configuração de Content Delivery Network (CDN) anteriores, esse comportamento ocorreu como projetado. Ter um objeto armazenado em cache com um cabeçalho Expires no passado resultou em um cabeçalho expires downstream "now". A data da "Última modificação" não foi alterada. Como resultado, uma resposta HTTP 304 da origem de uma solicitação if-modified-since (IMS) não atualizou cabeçalhos de objetos armazenados em cache com o Akamai. Quando um objeto foi armazenado em cache e expirou, nosso provedor de CDN sempre enviou uma solicitação "if-modified-since" (IMS) para a origem. Como a data da "Última modificação" é a mesma, nosso provedor de CDN recebeu uma resposta HTTP 304. Em seguida, o Time-To-Live (TTL) do cache de objetos foi atualizado para dez horas com base na configuração, mas o objeto e os cabeçalhos permaneceram inalterados.
Nesse ponto, atualizamos os metadados CDN para controlar a atualização dos cabeçalhos em cache.
A tag que nos permitiu alterar os cabeçalhos de capacidade de cache em uma resposta 304 do servidor de origem era:
<cache:header-update.allow>em</cache:header-update.allow>
Por padrão, nosso provedor CDN não atualiza os cabeçalhos em um objeto em cache com os cabeçalhos recebidos em uma resposta 304. Como resultado, uma vez o tempo do Expires é alcançado, o objeto permaneceria obsoleto no cache CDN (e para qualquer usuário final) até que a origem retornasse uma resposta 200 com um novo objeto. Uma vez que o tempo de expiração foi atingido, se a origem respondeu com um 304, o servidor CDN continuaria a revalidar com a origem em cada solicitação. Também serviria ao navegador do cliente um objeto que já estava expirado. Isso fez com que o navegador precisasse revalidar no próximo carregamento.
Quando ativamos a tag cache:header-update.allow, instruímos os servidores CDN a atualizar os cabeçalhos da diretiva de cache na resposta armazenada em cache se eles forem diferentes na resposta 304. Os cabeçalhos considerados cabeçalhos 'diretiva de cache' para este recurso são: Expires, Cache-Control, Edge-Control (e implicitamente Surrogate-Control).
Há também um controle relacionado sobre a frequência com que os cabeçalhos são atualizados no cache. Esse controle existe para evitar uma situação em que o servidor CDN precise gravar cabeçalhos em cache em todas as respostas, pois o servidor de origem está configurando um novo cabeçalho Expires com cada resposta (não no caso das respostas do Adobe Scene7). A configuração padrão para a frequência da atualização de cabeçalho é de um minuto, mas esse valor pode ser alterado com a tag de metadados:
<cache:header-update.max-frequency>1m</cache:header-update.max-frequency>
Quando o TTL é atingido, o objeto é considerado obsoleto nos EdgeServers. Uma solicitação do IMS é sempre enviada para a origem para verificar a hora da última modificação do mesmo objeto.
A alteração de metadados que fizemos permite atualizar os cabeçalhos junto com a resposta 304 da origem. Essa alteração não resultou em um download completo desse mesmo objeto se ele não foi modificado.
A solicitação if-modified-since para os servidores de origem só é feita quando o conteúdo é obsoleto. Ou seja, depois que o TTL expira, os cabeçalhos não são atualizados com frequência.