PHP Garbage Collector 引起的Session回話問題

php session有一個GC功能,就是Garbage Collector 。這個GC啓動的時候,會清除那些已經“超時 ”的session。它的工作原理是這樣的(以utblog.com爲例):

  1. 用戶訪問並登陸網站http://www.utblog.com ,這時候後臺會調用session_start來嘗試生成一個會話(如果已經有會話,則相當於一次有效會話請求)
  2. 對於這樣的每一次有效會話請求(Request),apache的php模塊會根據session相關的全局變量gc_probability/gc_divisor =>計算出啓動GC的概率,並由此概率來決定在這次請求中是否應該啓動GC 。舉例來說,session.gc_probability的缺省值爲1,session.gc_divisor的缺省值爲100,則啓動“垃圾回收”器的概率是1%,這就意味着在每100次請求中,會有可能清理一次過期會話
  3. 如果GC啓動,則GC會掃描當前會話 所 在路徑(session.save_path)下的所有會話文件,並根據另外一個全局變量session.gc_maxlifetime的多少來判斷哪些 session已經過期(“當前時間”與“會話文件的atime或者mtime”之間的差大於gc_maxlifetime:過期),並刪除這些過期的 session
  4. 如果你在一個session啓動後,長時間沒有任何交互操作(譬如,不停地碼字,沒有提交或者保存爲草稿),那麼你 的保存在後臺的會話文件將得不到機會被修改或者訪問,在gc_maxlifetime(缺省值1440秒=24分鐘)時間後,它有可能因失效而被清理,這 以後你再提交,就會因爲會話失效而報錯

由此可見,gc_maxlifetime設置爲24分鐘,對於寫某些文章來說還不夠。這 是一個原因,另外,session.save_path的缺省路徑在linux上是/tmp,很少有程序會修改這個設置。如果這臺服務器上有多個虛擬主 機,那麼,/tmp目錄下會存放許多不同session_name的會話文件。糟糕的是,php的GC不區分會話歸屬,它會根據它取得的 gc_maxlifetime來清理這個目錄下的所有過期session文件。

據以上分析,解決方案是:UTBLOG在.htaccess文件內添加了一條語句,將session.gc_maxlifetime的local value擴大爲14400(4小時) ,同時在後臺將session.save_path設置爲/tmp/utblog,這樣,utblog的會話文件就不受其他網站干擾了,而4小時 的失效時間,我想,無論如何應該夠用了。

測試下來,一切如我所願。

另, 如果直接改動/etc/php.ini當然也可以。如果沒有權限改動php.ini,也沒有權限改動apache的conf文件,.htaccess被禁 止,那麼直接修改plog的sessionmanager.class.php文件,在session_start行前添加 ini_alter("session.gc_maxlifetime", 14400)亦可。plog結構良好,只有這一處調用session_start,所以也只有這一處需要修改。我在本地做過測試,可以工作。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章