2008年5月31日 星期六

[Session]延長SESSION失效時間從24分鐘到4小時

延長SESSION失效時間從24分鐘到4小時



UTBlog寫文章,最後提交的關頭,有時候會出現“認證錯誤”資訊,提示再次登陸,再不可能“退回”到剛才編輯的頁面,結果是剛才的心血全部白費,痛哉!

究其原因,是因為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擴大為144004小時),同時在後臺將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,所以也只有這一處需要修改。我在本地做過測試,可以工作。

沒有留言:

wibiya widget