相關資訊
本類常用軟件
-
福建農村信用社手機銀行客戶端下載下載量:584204
-
Windows優(yōu)化大師下載量:416898
-
90美女秀(視頻聊天軟件)下載量:366961
-
廣西農村信用社手機銀行客戶端下載下載量:365699
-
快播手機版下載量:325855
由于PHP的工作機制,它并沒有一個daemon線程,來定時地掃描session信息并判斷其是否失效。當一個有效請求發(fā)生時,PHP會根據(jù)全局變量 session.gc_probability/session.gc_divisor(同樣可以通過php.ini或者ini_set()函數(shù)來修改) 的值,來決定是否啟動一個GC(Garbage Collector)。默認情況下,session.gc_probability = 1,session.gc_divisor =100,也就是說有1%的可能性會啟動GC。
GC的工作,就是掃描所有的session信息, 用當前時間減去session的最后修改時間(modified date),同session.gc_maxlifetime參數(shù)進行比較,如果生存時間已經超過gc_maxlifetime,就把該session刪 除。
那為什么會發(fā)生gc_maxlifetime無效的情況呢?
在默認情況下,session信息會以文本文件的形式,被保存在系統(tǒng) 的臨時文件目錄中。在Linux下,這一路徑通常為\tmp,在Windows下通常為C:\Windows\Temp。當服務器上有多個PHP應用時, 它們會把自己的session文件都保存在同一個目錄中。同樣地,這些PHP應用也會按一定機率啟動GC,掃描所有的session文件。
問 題在于,GC在工作時,并不會區(qū)分不同站點的session。舉例言之,站點A的gc_maxlifetime設置為2小時,站點B的 gc_maxlifetime設置為默認的24分鐘。當站點B的GC啟動時,它會掃描公用的臨時文件目錄,把所有超過24分鐘的session文件全部刪 除掉,而不管它們來自于站點A或B。這樣,站點A的gc_maxlifetime設置就形同虛設了。
找到問題所在,解決起來就很簡單了。修改session.save_path參數(shù),或者使用session_save_path()函數(shù),把保存session的目錄指向一個專用的目錄,gc_maxlifetime參數(shù)工作正常了。
還有一個問題就是,gc_maxlifetime只能保證session生存的最短時間,并不能夠保存在超過這一時間之后session信息立即會得到 刪除。因為GC是按機率啟動的,可能在某一個長時間內都沒有被啟動,那么大量的session在超過gc_maxlifetime以后仍然會有效。解決這 個問題的一個方法是,把session.gc_probability/session.gc_divisor的機率提高,如果提到100%,就會徹底解 決這個問題,但顯然會對性能造成嚴重的影響。另一個方法是自己在代碼中判斷當前session的生存時間,如果超出了gc_maxlifetime,就清 空當前session。
php session GC功能,就是Garbage Collector。這個GC啟動的時候,會清除那些已經“超時”的session。它的工作原理是這樣的:
用戶訪問并登陸網(wǎng)站,這時候后臺會調用session_start來嘗試生成一個會話(如果已經有會話,則相當于一次有效會話請求)
對于這樣的每一次有效會話請求(Request),apache的php模塊會根據(jù)session相關的全局變量gc_probability/gc_divisor =>計算出啟動GC的概率,并由此概率來決定在這次請求中是否應該啟動GC。舉例來說,session.gc_probability的缺省值為1,session.gc_divisor的缺省值為100,則啟動“垃圾回收”器的概率是1%,這就意味著在每100次請求中,會有可能清理一次過期會話
如果GC啟動,則GC會掃描當前會話所在路徑(session.save_path)下的所有會話文件,并根據(jù)另外一個全局變量session.gc_maxlifetime的多少來判斷哪些session已經過期(“當前時間”與“會話文件的atime或者mtime”之間的差大于gc_maxlifetime:過期),并刪除這些過期的session
如果你在一個session啟動后,長時間沒有任何交互操作(譬如,不停地碼字,沒有提交或者保存為草稿),那么你的保存在后臺的會話文件將得不到機會被修改或者訪問,在gc_maxlifetime(缺省值1440秒=24分鐘)時間后,它有可能因失效而被清理,這以后你再提交,就會因為會話失效而報錯
由此可見,gc_maxlifetime設置為24分鐘,對于寫某些文章來說還不夠。這是一個原因,另外,session.save_path的缺省路徑在linux上是/tmp,很少有程序會修改這個設置。如果這臺服務器上有多個虛擬主機,那么,/tmp目錄下會存放許多不同session_name的會話文件。糟糕的是,php的GC不區(qū)分會話歸屬,它會根據(jù)它取得的gc_maxlifetime來清理這個目錄下的所有過期session文件。
據(jù)以上分析,解決方案是:UTBLOG在.htaccess文件內添加了一條語句,將session.gc_maxlifetime的local value擴大為14400(4小時),同時在后臺將session.save_path設置為/tmp/utblog,這樣,utblog的會話文件就不受其他網(wǎng)站干擾了,而4小時的失效時間,我想,無論如何應該夠用了。
測試下來,一切如我所愿。
另,如果直接改動/etc/php.ini當然也可以。如果沒有權限改動php.ini,也沒有權限改動apache的conf文件,.htaccess被禁止,那么直接修改plog的sessionmanager.class.php文件,在session_start行前添加ini_alter("session.gc_maxlifetime", 14400)亦可。plog結構良好,只有這一處調用session_start,所以也只有這一處需要修改。我在本地做過測試,可以工作。
--------------------------------------------------------------------------
session.gc_probability integer
session.gc_probability 與 session.gc_divisor 合起來用來管理 gc(garbage collection 垃圾回收)進程啟動的概率。默認為 1。詳見 session.gc_divisor。
session.gc_divisor integer
session.gc_divisor 與 session.gc_probability 合起來定義了在每個會話初始化時啟動 gc(garbage collection 垃圾回收)進程的概率。此概率用 gc_probability/gc_divisor 計算得來。例如 1/100 意味著在每個請求中有 1% 的概率啟動 gc 進程。session.gc_divisor 默認為 100。
session.gc_maxlifetime integer
session.gc_maxlifetime 指定過了多少秒之后數(shù)據(jù)就會被視為“垃圾”并被清除。
Note:
如果不同的腳本具有不同的 session.gc_maxlifetime 數(shù)值但是共享了同一個地方存儲會話數(shù)據(jù),則具有最小數(shù)值的腳本會清理數(shù)據(jù)。此情況下,與 session.save_path 一起使用本指令。
Note: 如果使用默認的基于文件的會話處理器,則文件系統(tǒng)必須保持跟蹤訪問時間(atime)。Windows FAT 文件系統(tǒng)不行,因此如果必須使用 FAT 文件系統(tǒng)或者其他不能跟蹤 atime 的文件系統(tǒng),那就不得不想別的辦法來處理會話數(shù)據(jù)的垃圾回收。自 PHP 4.2.3 起用 mtime(修改時間)來代替了 atime。因此對于不能跟蹤 atime 的文件系統(tǒng)也沒問題了。
--------------------------------------------------------