5

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?

risposta

10

La risposta è stata trovata in una frase oscura scritto in un pezzo apparentemente non correlati di documentazione Amazon:

When you configure CloudFront to forward cookies to your origin [...] If-Modified-Since and If-None-Match conditional requests are not supported.

Strano, ma in effetti la realtà della situazione è di gran lunga peggiore; Non è che i cookie di inoltro ai server di origine disabilitino le richieste condizionali, ma piuttosto li disabilita a volte - al punto in cui il codice risultato HTTP (304 vs 200) è praticamente casuale.

È importante notare che verrai morso da questo strano comportamento anche se non stai utilizzando i cookie per tutto. E 'ancora assolutamente essenziale che il Forward Cookies discesa essere impostato su "Nessuno", come mostrato nell'immagine qui sotto:

enter image description here

Commutazione l'impostazione su "Nessuno" risolve il comportamento errante descritto nel mio post originale.

Questa soluzione presenta tuttavia un altro problema. Stai dicendo a CloudFront di eliminare completamente tutti i cookie prima di inoltrare la richiesta all'origine. Ma il tuo server di origine potrebbe necessario quei cookie. Inoltre, se si utilizza l'ELB (bilanciamento del carico) come origine, un cookie critico a cui l'ELB dipende per mantenere sessioni persistenti verrà completamente eliminato. Non bene.

La soluzione al problema di eliminazione dei cookie dipenderà dalla modalità di organizzazione del sito. Nel mio caso, la trasmissione di cookie (relativi alla sessione o altro) è necessaria solo quando si inviano dati AJAX a myDomain.com/ajax/. Poiché tutti gli URL dipendenti dai cookie rientrano nella categoria ajax/*, è stata creata una nuova regola comportamentale per tale percorso e in tale regola, e solo quella regola, il menu a discesa Inoltra cookie è impostato su "Tutti" anziché su "Nessuno" ".

Quindi eccolo. Spero che questo aiuti qualcuno.

Problemi correlati