• User Attivo

    Meglio avere i file fisicamente sul server

    Ciao a tutti,
    ho una domanda su una struttura per siti dinamici che mi gira per la testa già da un pò.

    Google fa differenza se i file del sito sono raggiungibili via url_rewriting in htaccess o se sono fisicamente presenti sul server?

    Mi spiego meglio, il sito che ho in mente è dinamico, in php e mysql.
    Pensavo di creare la solita struttura a variabili per estrarre la singola riga di mysql e mostrare gli articoli e poi tramite url_rewriting trasformare l'indirizzo
    miosito.it/articolo.php?id=1000 in miosito.it/miotitolo-1000.html

    Poi ho pensato che tutti i testi all'interno di mysql potrebbero diventare pesanti per il db (soprattutto considerando per assurdo che potrebbero diventare 1000000 di articoli con migliaia di righe di testo l'uno).

    Ho quindi pensato di salvare in fase di insert il testo in un file .txt, salvato in una cartella separata che vado a richiamare quando richiamo un articolo, salvando cosi nel db solo l'indirizzo del file.

    A questo punto mi è balenata per la testa un ultima idea: Perchè salvare solo il testo in un file? Perche non creare un template e salvare nella cartella separata direttamente la pagina completa di tutto il suo codice html? Naturalmente in php per poter lavorare di include.
    La parte del template sarebbe sempre uguale, ma ogni file avrebbe il suo testo e potrei richiamare direttamente miosito.it/articoli/miotitolo-1000.php

    Secondo voi ne vale la pena?
    Google preferisce file fisicamente salvati nell'indirizzo richiamato dal browser? Ho visto in giro che utilizza "If Modified Since header" ma non ho capito se può funzionare con strutture dinamiche o url_rewriter.
    Se all'indirizzo viene aggiunta una cartella si viene penalizzati? (potrei mettere tutti i filenella root ma se diventano miglaiia poi è dura aprirla in ftp e comunque verrebbe un casino)
    Val la pena avere una cartella in più o utilizzare url_rewriter?
    Google fa discriminazioni tra file html e php? Avrebbe senso modificare via url_rewriter tutte le estensioni php in html? O si torna da capo?

    Ciao
    Grazie


  • Moderatore

    Ciao aleban,
    @alebal said:

    Google preferisce file fisicamente salvati nell'indirizzo richiamato dal browser? Ho visto in giro che utilizza "If Modified Since header" ma non ho capito se può funzionare con strutture dinamiche o url_rewriter.
    Rispondo subito su questo punto:
    Google - come gli altri motori di ricerca - non ha assolutamente idea di dove provenga il contenuto, sia esso file fisico in una cartella o generato a run-time da lettura in database (in realtà alcuni response header del protocollo HTTP possono differire, p.es. content-length, ma in linea di massima il discorso è valido).
    Né gli interessa, per lui sono sono degli URL validi con dei valori di ritorno.

    L'header HTTP "if-modified-since" può essere usato anche per contenuti generati da database. Basta salvare su DB la data di ultima modifica della pagina, e si può facilmente aggiungerlo.

    Se ci pensi, le architetture delle applicazioni web di ultima generazione - i vari sapori di Rail e MVC - sono tutti contenuti generati a run-time, così come lo sono praticamente tutti i motori CMS e Wiki in uso.
    Davvero, per i motori di ricerca non fa alcuna differenza.

    @alebal said:

    Poi ho pensato che tutti i testi all'interno di mysql potrebbero diventare pesanti per il db (soprattutto considerando per assurdo che potrebbero diventare 1000000 di articoli con migliaia di righe di testo l'uno).

    Ho quindi pensato di salvare in fase di insert il testo in un file .txt, salvato in una cartella separata che vado a richiamare quando richiamo un articolo, salvando cosi nel db solo l'indirizzo del file.

    A questo punto mi è balenata per la testa un ultima idea: Perchè salvare solo il testo in un file? Perche non creare un template e salvare nella cartella separata direttamente la pagina completa di tutto il suo codice html? Naturalmente in php per poter lavorare di include.
    La parte del template sarebbe sempre uguale, ma ogni file avrebbe il suo testo e potrei richiamare direttamente miosito.it/articoli/miotitolo-1000.php
    Da programmatore, è il caso ti avverta:
    tipicamente un accesso a database è meno oneroso di un accesso a file system (quest'ultimo è una mazzata).

    (Nota: scusate se mi avventuro il qualche tecnicismo, cercherò di usare un linguaggio il più comprensibile anche a non programmatori)

    Quando accedi a file costringi l'applicazione a posizionare le testine del disco dalla posizione corrente all'inizio del file, e leggerlo serialmente. Non solo è pesante, ma non è scalabile: più letture concomitanti devono essere serializzate con conseguente tempo di attesa maggiore.
    Nota che ora sto semplificando molto le cose: dischi moderni hanno un minimo di caching e più testine.

    Si potrà obiettare che un web server di contenuti statici fa effettivamente lettura da file system, ma un web server è ottimizzato per fare caching dei contenuti più frequenti.

    L'accesso al database fisicamente alla fine è anch'esso una lettura di un dato salvato su file systems, ma intanto il motore del database tende a tenere un "file handle" aperto, di veloce accesso; il database è salvato solitamente in cluster attigui evitando troppo riposizionamenti di testine, il database ha un efficientissimo sistema di caching per cui riesce a risolvere in memoria le interrogazioni.
    Il database server in una buona architettura è fisicamente su un'altra macchina, per cui i dischi del web server sono risparmiati e vi è solo una rapida comuncazione di dati in rete locale (di solito si usa collegare web server e database server in modo che il traffico di lan interno generato da altre macchine non passi per lo stesso canale che collega i due server).

    Detto questo, non è che l'accesso a database sia poi così veloce, ma può essere ridotto drasticamente sia minimizzando le interrogazioni necessarie, sia facendo un caching applicativo.
    I CMS normalmente fanno proprio così: una volta reperiti i dati da database, si tengono il più possibile in memoria gli stessi.

    Se per timore di carico su database hai in mente solo le prestazioni in termini di velocità e tempi di risposta, allora direi che è comunque un'opzione migliore - in generale - del salvare i file più il template su file system.

    Se invece hai anche desiderio di non salvare troppi dati (magari sei in hosting con accesso limitato a un certo numero di MB mensili al database), tieni anche conto del fatto che il semplice testo HTML non è particolarmente oneroso da memorizzare. Puoi anche salvarlo in formato compresso e decomprimerlo alla bisogna, con algoritmi di compressione veloci. L'uso di caching applicativo poi - come già detto - ridurrebbe comunque drasticamente l'accesso al DB.

    Uno scenario in cui - se vuoi risparmiare spazio DB - invece la scelta potrebbe avere senso, è ad esempio lo storage delle immagini: spesso si trova più conveniente salvarle su file system e fare affidamento alle capacità di caching dei browser (e agli header di caching impostati dal web server).

    Spero d'esserti stato utile


  • User Attivo

    Utilissimo... grazie

    un ultimo approfondimento... pensavo "if-modified-since" fosse un qualche tipo di accesso fornito da server tipo su php.ini, non avevo capito fosse una cosa che posso passare io negli header.

    Quando mi dici:

    L'header HTTP "if-modified-since" può essere usato anche per contenuti generati da database. Basta salvare su DB la data di ultima modifica della pagina, e si può facilmente aggiungerlo.
    Cosa intendi?
    Io di solito passo nei miei file qualcosa di simile a questo:

    /*HEADER PER PAGINA DINAMICA*/
    # modifica dell'header relativo alla data dell'ultima modifica 
    header('Last-Modified: '.gmdate('D, d M Y H:i:s', $row_last_modified['data_ins']).' GMT');    
    

    Ma ho visto ora che esistono anche strutture più complesse tipo questa

    $fp = fopen($_SERVER["SCRIPT_FILENAME"], "r"); 
    $etag = md5(serialize(fstat($fp))); 
    fclose($fp);
    header("Cache-Control: must-revalidate");
    header("Last-Modified: ".gmdate("D, d M Y H:i:s", $SelectS['timestamp'])." GMT"); 
    header('Etag: '.$etag);
    header("Expires: -1");
    
    if ((@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $SelectS['timestamp']) && ( 
        trim($_SERVER['HTTP_IF_NONE_MATCH']) == $etag)) { 
        header("HTTP/1.1 304 Not Modified");
        exit;
    }
    

    Di quest'ultima non c'ho capito molto, vedo che comprende un header 304 e gli etag (di cui ho letto qualcosa sulle guide google ma non ho capito granche).
    Tu intendi una cosa simile a quest'ultima?

    Vedo che $etag viene ricavato aprendo un file, potrebbe essereil mio file .txt con salvato il contenutto?

    Non ho capito molto però questa riga:
    $fp = fopen($_SERVER["SCRIPT_FILENAME"], "r");

    Cosa apre? il file sul server? E se dinamico, inesistente o generato via url_rewriter, cosa apre?


  • Moderatore

    @alebal said:

    Quando mi dici:
    ...
    Cosa intendi?
    Scusa, nella mia risposta non sono stato preciso.

    • "if-modified-since" è un header http spedito dal client, tipicamente un browser, o un bot.
    • l'equivalente lato server, inviato nel response http, è "Last-Modified"

    Ti spiego a grandi righe come funziona:

    il browser chiede al web server una pagina, questi gliela serve con un header http Last-Modified corrispondente alla data di ultima modifica dalla pagina ("Last-Modified").
    Poniamo per esempio il server dica "eccola, l'ultima volta che è stata modificata è stato il primo aprile".

    La volta successiva che il browser deve mostrare la stessa pagina, può decidere di mostrare all'utente la copia in cache, oppure può decidere di richiederla al web server.
    Se decide di richiederla, e si ricorda di avere ricevuto la risorsa assieme a un Last-Modified 1° Aprile, nel richiederla può aggiungere l'header "http-if-modified-since" valorizzato alla stessa data. Che vuole dire: "io di questa pagina ho una versione aggiornata al primo aprile, se ne hai una più recente, ma la dai?"

    Il web server riceve la richiesta, vede il if-modified-since, controlla la data di ultima modifica, e se capisce di non avere una versione più recente risponde con un response code http 304, che non è un redirect, bensì vuole dire "guarda che la versione che hai è già la più aggiornata, usa pure quella".

    Se la pagina era leggera, da un punto di vista prestazionale si è risparmiato poco, perché la parte più onerosa del protocollo HTTP è la chiamata, ma se fosse una pagina corposa si risparmierebbe il tempo di download. E' un po' una via di mezzo tra il decidere di usare subito la pagina in cache, e il decidere di richiederla in toto.

    ETags è un meccanismo alternativo all'accoppiata "last-modified"/"if-modified-since"; non usa date (gli orologi potrebbero non essere sincronizzati), usa un sistema diverso:
    il server calcola in base al contenuto binario del file (tipicamente calcolato dal CRC) un piccolo testo identificativo univoco del file (o meglio quello che viene chiamato un hash, un codice quasi univoco ricavato dal binario completo; la probabilità che due file diversi abbiano stesso hash esiste ma è estremamente bassa). Questo valore lo restituisce nell'http header ETag.
    Quando il browser vuole richiedere se esiste una versione più aggiornata del file, lo richiede aggiungendo nell'header l'ETag precedente. Il server paragona il nuovo ETag, e se differente (non fa un paragone maggiore/minore, basta sia diverso) serve il nuovo file, altrimenti risponde HTTP 304 "guarda che la versione che hai è già aggiornata".

    ETags è efficiente e funziona bene per file statici, come per esempio le immagini. Per pagine generate dinamicamente è più pratico usare il meccanismo precedente (o non fornire del tutto informazioni del tipo "last-modified" o etag).

    Spero di averti fatto capire
    (purtroppo non sono fluente in PHP, non so aiutarti al meglio sulla precisa sintassi da usare)


  • User

    oltre quanto detto da Federico valuta bene dal punto di vista prettamente tecnico eventuali problemi legati al lock dei file. di solito dipende dal file system e dal sistema operativo.