2011-10-19 19 views
36

Dal manuale PHP, session.gc_probability e stato session.gc_divisor che gc si verificherà in base a questa probabilità. Ho capito.Chiarimento PHP Garbage Collection

Quello su cui non sono chiaro è se questa probabilità è su una sessione per sessione o in generale.

Quindi, se la mia probabilità è pari all'1% (1/100) del GC, ciò significa che se una sessione continua ad essere estesa, ogni volta che si verifica una modifica dell'1%, la sessione specifica verrà eliminata? O questo significa che l'1% di tutte le sessioni esistenti (così come quelle nuove) attiverà GC per tutte le altre sessioni esistenti?

Sono abbastanza sicuro che è il secondo, voglio solo essere sicuro.

Lo scopo di questa domanda è che sul nostro sito, voglio che gli utenti abbiano sessioni a lungo termine (6 mesi). Se l'1% di tutte le sessioni attiva GC, ciò rimuove efficacemente lo scopo di avere quella sessione a lungo termine, dato che GC finirà per verificarsi ogni ora o due.

+2

domanda molto interessante! +1 –

+0

correlati http://stackoverflow.com/questions/3865303/debian-based-systems-session-killed-at-30-minutes-in-special-cron-how-to-overri –

+0

Per chiunque altro stia leggendo questo tentativo quanto sopra, con 6 mesi di file di sessione può causare seri problemi di prestazioni (come indicato di seguito). Tuttavia, è possibile utilizzare session_set_save_handler() per scrivere un gestore di sessione personalizzato che utilizzerà il DB anziché il FS, annullando molte penalizzazioni prestazionali. – Meep3D

risposta

10

Ogni volta che uno script PHP viene eseguito e avvia la sessione, è probabile che esegua la scansione della cartella della sessione eliminando la vecchia sessione.

La pulizia eliminerà solo le sessioni a cui non è stato effettuato l'accesso entro un determinato periodo. Comunque PHP non garantisce che la sessione verrà distrutta entro quel tempo.

La vostra strategia di sessione a lungo termine dovrebbe funzionare bene, ma si potrebbe desiderare di ridurre 1% a qualcosa come 0,1%

Un'altra cosa da guardare fuori per è che il sistema operativo potrebbe ripulire la cartella/tmp durante riavvia quindi anche se PHP non lo farà.

+0

Ho ridotto la probabilità da 1/100 a 1/1000000 (0,000001%). Spero che risolva il problema. Inoltre, questo è un sito Magento, quindi le sessioni sono memorizzate in/var/session. Questa cartella, per quanto ne so, non viene toccata dal server (ma suppongo che verrà rimossa se "Flush cache storage" viene scelto dall'amministratore di Magento). – pspahn

+0

Oh, lascia sperare che Magento non implementa sessioni alternative che ignorerebbero le impostazioni gc_ *. – romaninsh

+5

e l'effetto collaterale di ridurre la probabilità è che si riempirà il disco rigido con sessioni precedenti. e le sessioni richiederanno sempre più tempo per trovarle e caricarle, e alla fine della giornata c'è ancora una minima possibilità che le sessioni verranno cancellate comunque (anche se è remotamente piccola). Puoi guardare opzioni alternative come scrivere il tuo gestore di sessione e controllare esattamente quali sessioni vuoi rimuovere e quando. non è cosi difficile. http://www.php.net/manual/en/function.session-set-save-handler.php – bumperbox

2

Non sono un esperto in questo, ma dalla lettura del manuale, attirerei la vostra attenzione su un'altra impostazione, session.gc_maxlifetime. Dalla documentazione:

session.gc_maxlifetime specifica il numero di secondi dopo che i dati verranno visti come 'spazzatura' e potenzialmente ripulito. La raccolta dei dati inutili può verificarsi durante l'avvio della sessione (in base a session.gc_probability e session.gc_divisor).

Quindi, se si imposta questa impostazione ad un valore adatto (60 * 60 * 24 * 365/2 per un anno e mezzo, in modo da 15768000), quindi i dati appropriati non saranno ammissibili per la raccolta dei rifiuti, non importa ciò che le altre impostazioni sono.

+1

Ho già impostato gc_maxlifetime a 15552000 (180 giorni) - Sembrava che tutto funzionasse correttamente sul sito dev, ma dopo averlo spinto dal vivo, ha funzionato per un po 'prima che iniziasse a rimandare gli utenti alla pagina di accesso. – pspahn

+7

questo valore significa "secondi dopo la creazione della sessione" o "secondi dopo l'ultima modifica"? –

+0

Dovrebbe essere una combinazione di mettere il garbage collector in modo che i dati della sessione siano lì nel dizionario, ma anche estendere la durata dei cookie in modo da salvare l'ID di sessione univoco per quella riga di dati di sessione se ho capito bene. – vikingben

7

l'ultima volta che ho guardato la fonte ogni chiamata a session_start() "ha tirato i dadi" per così dire, usando il divisore e la probabilità. Se si preme, quindi eliminerebbe tutti i file dalla directory session.save_path che erano precedenti a session.gc_maxlifetime. Ho dimenticato se ha usato la modifica o il tempo di accesso del file, anche se non dovrebbe importare in normali circostanze, perché php sovrascrive il file di sessione per impostazione predefinita al termine dell'esecuzione dello script, quindi i tempi di accesso e mod dovrebbero quasi sempre corrispondere molto da vicino.

// Rough psuedo code of how php's session_start() function works regarding garbage collection. 
function session_start() { 
    $percentChanceToGC = 100 * ini_get('session.gc_probability')/ini_get('session.session.gc_divisor'); 
    $shouldDoGarbageCollection = rand(1, 100) < $percentChanceToGC; 
    if ($shouldDoGarbageCollection) { 
     $expiredCutoffTime = time() - ini_get('session.gc_maxlifetime'); 
     foreach (scandir(ini_get('session.save_path')) as $sessionFile) { 
      if (filemtime($sessionFile) < $expiredCutoffTime) { 
       unlink($sessionFile); 
      } 
     } 
    } 

    // ... rest of code .... 
} 

non so quanti file sessione si sta andando a finire con l'avere rimanere in giro se si desidera loro di vivere per un minimo di 6 mesi. Considera che potrebbe essere necessario un po 'di tempo prima che php pubblichi molte migliaia di file per determinare la loro età. Forse prendere in considerazione altre opzioni per la conservazione duratura di questi dati. Oppure puoi disabilitare php gc e basta eseguire un cron job per eliminare i file di sessione non aggiornati.Altrimenti, quell'1% delle richieste attiverà gc e dovrà aspettare php; in altre parole potrebbe essere in ritardo.