1. 程式人生 > >關於php session鎖的機制的個人理解

關於php session鎖的機制的個人理解

作為一個phper,程式設計的時候經常會用到session和cookie,之前一直對session的理解比較片面,閒來無事,抽了點時間來稍微深入的理解一下它的執行原理和一些可能會在實際運用中會遇到的問題。

假設第一個使用者在登入頁面login.php 填寫了自己的使用者名稱,(只為演示,忽略掉密碼)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>SESSION登入測試</title>
</head>
<body> <form action="do.php?type=login" method="post"> <input type="text" name="username" /> <input type="submit"> </form> </body> </html>

提交到後臺do.php做登入處理,
一般情況下,程式處理登入請求會很快,但是在高併發和伺服器高負載的情況下,速度會有所減慢,我們用sleep函式來模擬程式處理的緩慢情況,設定為10秒

<?php
session_start(); if($_GET['type'] == 'login'){ $username = $_POST['username']; $_SESSION['username'] = $username; sleep(10); } ?>

與此同時,第二個使用者也在登入頁面提交了使用者名稱,後臺接收使用者名稱做session,這次為了避開sleep函式,用另一個分支來處理,

if($_GET['type'] == 'login2'){
        $username = $_POST
['username']; $_SESSION['username'] = $username; }

第二個使用者的瀏覽器一直停留在轉圈圈的等待狀態,10秒過後,等第一個使用者登入請求處理完畢,第二個使用者才處理了登入請求,這個就是,我們常說的,session阻塞機制,

session預設以檔案儲存,當一個使用者訪問session_start頁面後,這個時候,就會預設建立一個包含session_id檔名,並且這個時候,會對檔案進行鎖定。如果這個使用者點選連結,又訪問一個該站session_start網頁。這是,由於session_id一樣,這個頁面也有讀取鎖定該使用者存放session檔案。 由於,第一個頁面沒有執行完,它一直鎖定了該檔案。 第2個頁面就不能獲取鎖,一直處於等待狀態。

這樣一個看似小的問題,實際上,如果網站上面有大量使用者訪問,會導致session讀取檔案一直阻塞等待著。使用者瀏覽器一直跟伺服器保持連線,會消耗很多伺服器資源。web伺服器活躍連線數也會增大,可能很快就會耗費完連線資源,出現拒絕伺服器。百度了下,其實php裡面的session_commit 函式就能幫助我們解決這個問題。我們看下下面程式碼執行過程:

<?php
    session_start();

    if($_GET['type'] == 'login'){
        $username = $_POST['username'];

        $_SESSION['username'] = $username;

        session_commit();

        sleep(10);
        echo $_SESSION['username'];
    }
?>

生成session後 ,直接呼叫session_commit函式,相當於操作完session檔案後直接提交關閉session,檔案鎖開啟,後面的使用者使用session不再被阻塞,問題解決。

總結:
1.有對session進行寫入頁面,建議修改完$_SESSION後,隨手直接呼叫session_commit()
2.多次開啟並且寫入,這個不建議使用,比較開啟檔案,寫入都是耗費時間的。如果能一次搞定的,就不要做多次了。 除非中間執行很耗時的業務。