Risorse con versione per migliorare la cacheabilità

6

Ecco un concetto di API che potrebbe essere utile per l'ottimizzazione delle prestazioni. È un esempio di scadenza cache basata su chiave applicata a una rete più ampia -il contesto generale invece dello scenario interno in stile Memcached per cui è maggiormente utilizzato.

Voglio rendere le chiamate API quasi come memorabili nella cache come immagini statiche. Usando un sottoscrittore di notizie / feed come esempio, che potremmo eseguire il polling ogni ora, l'idea è di inviare un timestamp aggiornato per ultimo insieme a ciascun argomento (potrebbe facilmente essere un numero di versione o un checksum):

{
  username: "Wendy",
  topics: [{
    name: "tv",
    updated: 1357647954355
  },
  {
    name: "movies",
    updated: 1357648018817
  },
  {
    name: "music",
    updated: 1357648028264
  }]
}

Per essere chiari, questa risorsa proviene direttamente dal server ogni volta e non viene memorizzata nella cache sul bordo o dal client. Sono le nostre chiamate successive per argomenti che possiamo memorizzare in modo aggressivo, grazie al timestamp.

Supponendo di voler sincronizzare tutti gli argomenti, avremmo "N" ulteriori chiamate da eseguire in un'implementazione naieve ( /topics/tv ecc.). Ma a causa del timestamp, possiamo costruire un URL come /topics/tv/1357647954355.json . Il client di solito non effettua alcuna chiamata se ha già visto (e memorizzato nella cache) la stessa versione di quella risorsa. Inoltre, anche se è nuovo per il client, una cache di bordo (ad esempio un reverse proxy come Squid, Varnish o un servizio come Cloudflare) probabilmente ha visto prima, perché qualche altro utente ha probabilmente aperto il l'ultima versione di questo argomento già. Quindi continuiamo a ignorare il server delle applicazioni; il server crea sempre topic JSON una volta dopo l'aggiornamento della risorsa sottostante. Quindi, al posto delle chiamate N + 1 al server, il client probabilmente effettua un numero molto più piccolo di chiamate e tali chiamate raramente colpiranno comunque il server delle app.

Ora per la mia domanda Tutto ciò sembra fattibile e degno di essere fatto, ma la mia domanda è se c'è qualche arte precedente per questo genere di cose e, in particolare, qualsiasi standard HTTP per supportarlo. Inizialmente pensavo al caching condizionale (ETags e date modificate) e penso che avrebbero aiutato a ottimizzare ulteriormente questa configurazione, ma non credo che siano la risposta. Sono sottilmente diversi, perché richiedono che le chiamate vengano passate al server delle applicazioni per verificare che qualcosa sia cambiato. L'idea qui è che il cliente dice "Conosco già l'ultima versione, per favore invia quella risorsa a me". Non penso che ci sia uno standard HTTP per questo, ed è per questo che propongo uno schema URL come /topics/tv/1357647954355.json invece di un header simile ad ETag. Credo che alcuni CDN funzionino in questo modo e per me è sorprendente se non ci sia un vero standard HTTP intorno.

Aggiornamento: A ben riflettere, un caso speciale importante di questo è ciò che fa un browser Web quando recupera una nuova pagina HTML. Sappiamo che richiederà immediatamente CSS + JS, quindi è possibile utilizzare lo stesso trucco di versioning / timestamp per garantire che le risorse statiche siano compatibili con la cache. Che questo trucco non sia stato formalizzato dalle specifiche mi dà fiducia che purtroppo non esiste uno standard HTTP per questo. link

    
posta mahemoff 08.01.2013 - 14:11
fonte

2 risposte

1

Per quanto posso dire, non hai davvero bisogno di alcun supporto HTTP specifico per quello che vuoi fare. Al centro, sembra che tu voglia essere in grado di prendere un frammento json come

topics: [{
    name: "tv",
    updated: 1357647954355
},

e trasformalo in

GET /topics/tv/1357647954355.json

e lo hanno restituito da una edge cache o da un altro store senza colpire il server, presumendo ovviamente che un neighbor (ad una qualche definizione di Internet di local) abbia già richiesto la stessa pagina e quindi la cache di bordo locale lo abbia cache-hints, ecc.?

Finché il tuo javascript di elaborazione del tuo json originale può eseguire il secondo AJAX-GET, allora dovresti ottenere più o meno ciò che ti aspetti che accada, che il numero di richieste che colpiscono il server centrale per il singolo TV / URL sono poche , data la loro elevata capacità di cucitura.

    
risposta data 08.01.2013 - 22:45
fonte
1

La soluzione è intelligente, ma metterei in dubbio se c'è anche bisogno di fare una richiesta non cache per recuperare il JSON per l'elaborazione dinamica usando JavaScript.

Se dovessi semplicemente emettere la versione più recente degli URL direttamente in <script> e <link> elementi come parte della pagina HTML che servi, ciò comporterebbe una richiesta di risorse in meno. Immagino che dipenda esattamente da quanto è grande l'HTML che stai servendo in primo luogo, ma anche che potrebbe essere servito con un ETag basato su un hash dell'ultima data dipendente delle risorse e, supponendo che non siano cambiati , che risulterebbe in un 304 non modificato per l'HTML stesso.

In questo modo eviti assolutamente qualsiasi magia JavaScript (che deve aggiungere ingigantire anche la logica di download) e ridurre le richieste di almeno una.

    
risposta data 18.01.2013 - 23:08
fonte

Leggi altre domande sui tag