關於session和memcache的若干問題

實現Session的功能,基本上是經過
 *          設置客戶端的Cookie來保存SessionID,
 *          而後把用戶的數據保存在服務器端,最後通

 *          Cookie中的Session Id來肯定一個數據是不是用戶的,


原始
session.save_handler = files


mem:

session.save_handler = memcache

session.save_path = "tcp://192.168.0.26:13001,tcp://192.168.0.26:13002"

session.use_cookies = 1 php

 


//memcache 配置數組
$memcache_servers=array(
      array("host"=>"192.168.0.26",
            "port"=>"14001",
            "persistent"=>true,
            "weight"=>1,
            "timeout"=>1,//1爲默認值,單位爲秒
            "retry_interval"=>2,
            "status"=>true,
            "failure_callback"=>"memcacheConnectLog"
      ),
      array("host"=>"192.168.0.26",
            "port"=>"14002",
            "persistent"=>true,
            "weight"=>1,
            "timeout"=>1,//1爲默認值,單位爲秒
            "retry_interval"=>2,
            "status"=>true,
            "failure_callback"=>"memcacheConnectLog" //寫入日誌函數
      )
); 數據庫

 

 

 

一直以來,因爲php自己的session機制不能跨機,令不少phper感到不爽,如今流行的解決方案主要有:
1)使用數據庫來實現
2)本身寫server端,經過改寫session處理函數來請求
3)使用nfs等跨機存儲來保存session
4)使用memcache來保存
5)使用zend platform提供的解決方案

其中的1-4都是經過改用能夠跨機的儲存機制,再使用session_set_save_handler()來實現,5是zend公司的商業產品(不過據以前在使用的同事反映,效果不太滿意),以上的方案,各有利弊,不在本文討論範圍

不管是用memcache,仍是db,nfs,其原理是同樣的,都是經過session_set_save_handler函數來改變默認的處理方式,經過指定回調函數來自定義處理,能夠參考手冊的session_set_save_handler()函數部分,有例子,比較容易明白

如下是一些我在使用memcache來實現時的一些記錄:
1)使用類來實現時,各回調函數都定義爲靜態方法,在類的構造中使用session_set_save_handler註冊回調函數, 如:
session_set_save_handler(
                array('memSession', 'open'),
                array('memSession', 'close'),
                array('memSession', 'read'),
                array('memSession', 'write'),
                array('memSession', 'destroy'),
                array('memSession', 'gc')
          );
memSession爲類名,要使用session,則先new memSession,再session_start();


2)生存期和垃圾回收
memCache的set命令有生存期,即便用set命令添加值時,可加上lifetime,此時間能夠做爲session的生存期,用戶在此時間內沒有動做,則會失效,但有動做則不會失效(由於每個腳本結束時,都會執行write和close,此時lifetime就會被更新了),固然,若是使用 cookie傳遞SID,則控制SESSION生存期能夠用:ini_set('session.cookie_lifetime',time)來設定, 這實際上是控制cookie的有效時間,若是session賴以生存的cookie消失了,固然session也就活不了,使用 cookie_lifetime來控制的話,不管有無動做,都將在指定的時間後過期

gc是指垃圾回收,在session中是指清理過時的session數據,影響的參數有:
session.gc_maxlifetime 被視爲垃圾前的生存期,超過此時間沒有動做,數據會被清走
注意的是,gc不是每次啓動會話都會被執行,而是由session.gc_probability 和 session.gc_divisor的比率決定的

結論:控制SESSION的生存期有幾種方法
一是cookie_lifttime,這種方式不管有無動做,都會在指定時間內銷燬
二是在read中根椐保存時間控制,此方法在有動做時時間會一直有效
三設定session.gc_probability 和 session.gc_divisor的比率爲1(即每次會話都會啓用gc),再設定gc.maxlifetime來指定生存期,此方法也是在用戶有動做時時間一直有效

3)回調函數的執行時機
open 在運行session_start()時執行
read 在運行session_start()時執行,由於在session_start時,會去read當前session數據並寫入$_SESSION變量
destroy 在運行session_destroy()時執行
close 在腳本執行完成或調用session_write_close() 或 session_destroy()時被執行,即在全部session操做完成後被執行
gc 執行機率由session.gc_probability 和 session.gc_divisor的值決定,時機是在open,read以後,即session_start會相繼執行open,read和gc
write 此方法在腳本結束和使用session_write_close()強制提交SESSION數據時執行

結論:
session_start //執行open(啓動會話),read(讀取session數據至$_SESSION),gc(清理垃圾)
腳本中間全部對$_SESSION的操做均不會調用這些回調函數
session_destroy //執行destroy,銷燬當前session(通常是刪除相應的記錄或文件),相應地,此回調函數銷燬的只是session的數據,但此時

var_dump一下$_SESSION變量,仍然有值的,但此值不會在close後被write回去
session_write_close() //執行write和close,保存$_SESSION至存儲,如不手工使用此方法,則會在腳本結束時被自動執行

清晰了以上信息,將對你清楚瞭解SESSION的工做原理有很大的幫助...

4)直接使用memcache做session處理
在我寫了一系列的memcache來保存session的代碼後,無心中發現,能夠直接在php.ini中設定使用memcache做爲session處理,而無須另外編碼,方法是:
修改php.ini中的如下值
session.save_handler = memcache
session.save_path = 'tcp://host1:11211' #有多個時直接用","分隔便可
若是隻想在特定的應用裏使用memcache儲存session,能夠使用ini_set的方法對以上兩個參數進行設定

要測試一下是否真正用上了memcache,能夠先捕足到使用的PHPSESSID,再做爲KEY用memcach去讀一下,就清楚了 數組

相關文章
相關標籤/搜索