摘要:當(dāng)開(kāi)啟session_start以后,這個(gè)session會(huì)一直開(kāi)啟,并且被一個(gè)用戶使用。其他用戶開(kāi)啟session的話要等待第一個(gè)session用戶關(guān)閉以后才可以開(kāi)啟session,這樣就造成了session阻塞...
當(dāng)開(kāi)啟session_start以后,這個(gè)session會(huì)一直開(kāi)啟,并且被一個(gè)用戶使用。其他用戶開(kāi)啟session的話要等待第一個(gè)session用戶關(guān)閉以后才可以開(kāi)啟session,這樣就造成了session阻塞。
結(jié)合了PHP的Session機(jī)制,找到了阻塞的原因。由于PHP的Session信息是寫入文件的,1個(gè)客戶端占有1個(gè)session文件。因此,當(dāng) session_start被調(diào)用的時(shí)候,該文件是被鎖住的,而且是以讀寫模式鎖住的(因?yàn)槌绦蛑锌赡芤薷膕ession的值),這樣,第2次調(diào)用 session_start的時(shí)候就被阻塞了。
解決session阻塞,使用session_write_close函數(shù)或session_commit函數(shù)(session_write_close的別名),作用是Write session data and end session,也就是寫session的數(shù)據(jù),同時(shí)關(guān)閉這個(gè)session。因此,我們可以在用完session之后,調(diào)用這個(gè)函數(shù)關(guān)閉session 文件即可解除鎖定。一般,session是用來(lái)記錄用戶身份信息的,以便PHP進(jìn)行身份認(rèn)證,因此完全可以將session的讀寫放在頁(yè)面剛開(kāi)始執(zhí)行的時(shí)候,在執(zhí)行完以后,馬上調(diào)用session_write_close函數(shù)即可。
舉個(gè)例子,一目了然:
如果用戶登錄后需要處理某些數(shù)據(jù)時(shí),執(zhí)行的時(shí)間比較長(zhǎng)(如5-6秒時(shí)),這時(shí)頁(yè)面執(zhí)行一個(gè)ajax去獲取當(dāng)前執(zhí)行的進(jìn)度時(shí),就會(huì)出現(xiàn)在一直等待的問(wèn)題,也就是session阻塞。
a.php
session_start(); $_SESSION['username'] = 'yzmcms'; $_SESSION['time'] = time(); // 解決session阻塞 session_write_close(); // 執(zhí)行大量業(yè)務(wù)邏輯代碼,時(shí)間大約5秒鐘 sleep(5); var_dump($_SESSION);
b.php
session_start(); var_dump($_SESSION);
如果a.php不加session_write_close函數(shù)的話,訪問(wèn)b.php的時(shí)候?qū)⑹堑却校钡絘.php執(zhí)行完成后,b.php才會(huì)返回結(jié)果。
補(bǔ)充:
session默認(rèn)是文件存儲(chǔ),也可以存在數(shù)據(jù)庫(kù)或內(nèi)存,存入內(nèi)存可以使用Memcached和Redis技術(shù),如果存入數(shù)據(jù)庫(kù)或內(nèi)存,則這些數(shù)據(jù)就是共享的可以同時(shí)讀取。如以上代碼。Redis讀取時(shí)候,是共享的,不會(huì)出現(xiàn)等待。但是,我們會(huì)發(fā)現(xiàn),Redis連接數(shù),還是會(huì)保持著。并且連接數(shù)會(huì)增加,如果這個(gè)時(shí)候,你設(shè)置的Redis連接數(shù)過(guò)小,你會(huì)發(fā)現(xiàn),很快Redis就掛掉了,所以還是建議使用以上函數(shù)來(lái)做處理。
網(wǎng)友評(píng)論:
大佬就是大佬
2021-07-08 20:10:55 回復(fù)
網(wǎng)友評(píng)論:
2021-05-21 19:29:23 回復(fù)