Una griglia di server Web EC2 è in esecuzione dietro un bilanciamento del carico ELB. L'ELB è dietro la rete di content delivery CloudFront di Amazon. Le reti di Content Delivery sono molto nuove per me. La mia comprensione è che CloudFront dovrebbe accelerare le prestazioni memorizzando nella cache i contenuti statici ai suoi "bordi". Ma questo non è ciò che sta accadendo.Amazon CloudFront non restituisce costantemente 304 (non modificato) per il contenuto statico invariato?
Considerate le mie istanze EC2 il cui contenuto dovrebbe avere sempre una durata di cinque minuti. Per i contenuti statici questo di solito significa che dichiara quanto segue nel mio file web.config:
<staticContent>
<clientCache cacheControlCustom="public" cacheControlMode="UseMaxAge" cacheControlMaxAge="00.00:05:00"/>
</staticContent>
... e per la roba dinamica, di solito significa eseguire i seguenti comandi contro un oggetto HttpResponse:
resp.Cache.SetCacheability(HttpCacheability.Public);
resp.Cache.SetMaxAge(TimeSpan.FromMinutes(5));
Con quello come sfondo ...
Quando il mio browser colpisce direttamente l'ELB, tutto funziona come previsto. Firebug mostra costantemente che 304 (non modificato) viene restituito per il contenuto esistente nella cache del browser, ha superato la scadenza di cinque minuti, ma non è stato modificato sul server. Qui ci sono le intestazioni di risposta per un download di defs.js, ad esempio:
HTTP/1.1 304 Not Modified
Accept-Ranges: bytes
Cache-Control: public,max-age=300
Date: Tue, 22 Apr 2014 13:54:16 GMT
Etag: "0152435d158cf1:0"
Last-Modified: Tue, 15 Apr 2014 17:36:18 GMT
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Connection: keep-alive
IIS correttamente vede che il file non è stato modificato dal 15 aprile e restituisce 304.
Ma guarda cosa succede quando il file viene afferrato tramite CloudFront.
HTTP/1.1 200 OK
Content-Type: application/x-javascript
Content-Length: 205
Connection: keep-alive
Accept-Ranges: bytes
Cache-Control: public,max-age=300
Date: Tue, 22 Apr 2014 14:07:33 GMT
Etag: "0152435d158cf1:0"
Last-Modified: Tue, 15 Apr 2014 17:36:18 GMT
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Age: 16
X-Cache: Hit from cloudfront
Via: 1.1 0f140ef1be762325ad24a7167aa57e65.cloudfront.net (CloudFront)
X-Amz-Cf-Id: Evfdhs-pxFojnzkQWuG-Ubp6B2TC5xbunhavG8ivXURdp2fw_noXjw==
In questo caso CloudFront costringe il browser per scaricare l'intero file di nuovo, anche se, come si può vedere:
(a) sa che il file non è stato modificato dal 15 aprile (vedi ultima - Intestazione modificata) e (b) CloudFront ha una copia memorizzata nella cache del file (vedi intestazione X-Cache)
Forse ti starai chiedendo se il mio browser sta inviando un'intestazione If-Modified-Since valida . Certo che lo è. Ecco le intestazioni delle richieste:
GET /code/shared/defs.js HTTP/1.1
Host: d2fn6fv5a0cu3b.cloudfront.net
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:28.0) Gecko/20100101 Firefox/28.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Referer: http://d2fn6fv5a0cu3b.cloudfront.net/
Connection: keep-alive
If-Modified-Since: Tue, 15 Apr 2014 17:36:18 GMT
If-None-Match: "0152435d158cf1:0"
Cache-Control: max-age=0
È una situazione strana. Se mi siedo davanti al mio browser e continuo a caricare la pagina Ricarica (Cmd-R), forse circa la metà delle volte che CloudFront restituirà correttamente un 304 e l'altra metà del tempo restituirà in modo non corretto 200 insieme a tutto il contenuto . Aspettare la scadenza di cinque minuti prima di interagire con la pagina produce principalmente 200 e solo alcuni 304. Questo strano comportamento si applica a tutti i file (.css, .js, .png, ecc.) A cui si fa riferimento nella pagina HTML e per la stessa pagina HTML contenente. So che la mia app è codificata correttamente perché, come accennato in precedenza, colpire direttamente il ELB senza passare attraverso i risultati CloudFront nel risultato 304 atteso. Qualche idea?