這個問題不少作php開發朋友應該都有遇到過,一個啓用了session_start 頁面,因爲執行時間過長。致使通一個用戶訪問,另一個很簡單的啓用session_start頁面一直阻塞着。 直到第一個頁面執行完了。第二個頁面就能夠讀取。這個就是,咱們常說的,session阻塞機制。php
session默認以文件保存,當一個用戶訪問session_start頁面後,這個時候,就會默認建立一個包含session_id文件名,而且這個時候,會對文件進行鎖定。若是這個用戶點擊連接,又訪問一個該站session_start網頁。這是,因爲session_id同樣,這個頁面也有讀取鎖定該用戶存放session文件。 因爲,第一個頁面沒有執行完,它一直鎖定了該文件。 第2個頁面就不能獲取鎖,一直處於等待狀態。web
這樣一個看似小的問題,實際上,若是網站上面有大量用戶訪問,會致使session讀取文件一直阻塞等待着。用戶瀏覽器一直跟服務器保持鏈接,會消耗不少服務器資源。web服務器活躍鏈接數也會增大,可能很快就會耗費完鏈接資源,出現拒絕服務器。瀏覽器
用memcache保存用戶session,相比讀取文件有很大速度提高。並且能夠作到多服務器共享session。確實很方便,這個時候,咱們發現不會出現用文件保存session鎖定清理。memcached讀取時候,是共享的,不會出現等待。可是,咱們會發現,memcached鏈接數,仍是會保持着。而且,鏈接數會增長,若是這個時候,你設置的memcached鏈接數太小,你會發現,很快memcached就掛死了。 這也是,作memcache接管session時候,常常遇到問題。 有時候,web服務器不少,session(memcache)不多。發現memcache莫名其妙死掉,可能跟這個有關係。太多反映很慢的頁面(啓動session),會致使佔用了大量memcached鏈接數。服務器
其實,經過file或者session,若是處理耗時頁面,都會帶來服務器資源很大消耗。其實咱們通常寫入session或者讀取時候,若是本身可以控制。用完了,就關閉掉文件鎖,或者mem鏈接。就會自動釋放資源,其實,php裏面的:session_write_close,session_commit 函數就能作到改功能。咱們看下下面代碼執行過程:session
<?php ini_set('session.save_path','/tmp/'); function open($save_path, $session_name) { echo __FUNCTION__,"<br />"; return(true); } function close() { echo __FUNCTION__,"<br />"; return(true); } function read($id) { echo __FUNCTION__,"<br />"; } function write($id, $sess_data) { echo __FUNCTION__,"<br />"; return(true); } function destroy($id) { echo __FUNCTION__,"<br />"; return(true); } function gc($maxlifetime) { echo __FUNCTION__,"<br />"; return true; } session_set_save_handler("open", "close", "read", "write", "destroy", "gc"); register_shutdown_function('test'); function test() { echo __FUNCTION__,"<br />"; } session_start(); echo 'aaaaa',"<br />";
啓動」session_start」 會自動執行,open,read函數,而後頁面執行完,會執行shutdown函數,最後會把session寫入進去,而後執行close關閉文件。從session_start 到頁面結束,會一直鎖定文件或者保持鏈接的。ide
咱們若是 執行完session_start後,執行」session_commit();」 看看結果memcached
執行過程:執行commit後,直接會調用,wirte,close操做。直接關閉文件或者關閉鏈接(memcache)了。 函數
第一次寫入後,而後提交,再次打開寫入,而後再次提交。咱們發現,2次數據都保存到用戶session中了。性能
1.只讀取session頁面,建議打開後,就直接commit,這是$_SESSION變量已經生成了。優化
2.有對session進行寫入頁面,建議修改完$_SESSION後,直接調用commit
3.屢次打開而且寫入,這個不建議使用,比較打開文件,寫入都是耗費時間的。若是能一次搞定的,就不要作屢次了。 除非,中間執行很耗時的業務。
後記:其實,使用完session,隨手commit也不是壞事,養成習慣後。能夠節省性能,減小服務器開銷。是個不錯選擇!