首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 多伺服器 Session 共享:NFS 方案完整部署教學

     編輯:PHP 綜合知識

前言:為什麼需要 Session 共享?

在多伺服器架構(負載均衡、微服務、多子域名系統)中,使用者請求可能被分發到不同的 PHP 節點。若 Session 儲存在本地檔案系統,使用者在節點 A 登入後,跳轉到節點 B 時就會丟失登入狀態。解決此問題的核心在於:**讓所有節點讀寫同一份 Session 資料**。

NFS (Network File System) 是一種成熟的網路檔案系統協定,透過掛載遠端目錄到本地,讓多台伺服器共享同一組 Session 檔案。本文將詳細說明從 PHP 設定到 NFS 架設的完整流程。

第一階段:PHP Session 儲存路徑優化

1. 修改 php.ini 啟用分級目錄

大量 Session 檔案集中在單一目錄會導致 inode 耗盡、目錄查找緩慢。PHP 內建支援分級雜湊目錄:

session.save_path = "2;/tmp/php_sess"

參數解析:

  • 2:分級深度(兩層子目錄)
  • /tmp/php_sess:基礎儲存目錄
  • 實際結構:/tmp/php_sess/a/b/sess_...,每層 16 個十六進位子目錄(0-9, a-f),總共 256×256 = 65,536 個葉子目錄,極大降低單目錄檔案數。

2. 建立分級目錄腳本

PHP 原始碼附贈 mod_files.sh 可自動建立目錄樹。儲存路徑建議:/usr/local/server/php/include/php/ext/session/mod_files.sh

#!/bin/sh
# 用法: mod_files.sh basedir depth [numberofsubdirs]
# 範例: ./mod_files.sh /tmp/php_sess 2 16

if test "$2" = ""; then
    echo "usage: $0 basedir depth [numberofsubdirs]"
    exit 1
fi

if test "$2" = "0"; then exit 0; fi

hash_chars="0 1 2 3 4 5 6 7 8 9 a b c d e f"
if [ ! -z $3 ]; then
    if test "$3" -a "$3" -eq "32"; then
        hash_chars="$hash_chars g h i j k l m n o p q r s t u v"
        if test "$3" -eq "64"; then
            hash_chars="$hash_chars w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z - ,"
        fi
    fi
fi

for i in $hash_chars; do
    newpath="$1/$i"
    mkdir $newpath || exit 1
    sh $0 $newpath `expr $2 - 1` $3
done

3. 執行建立目錄

chmod +x mod_files.sh
cd /usr/local/server/php/include/php/ext/session/
./mod_files.sh /tmp/php_sess 2 16

第二階段:NFS 伺服器端設定 (以 192.168.0.1 為例)

1. 安裝 NFS 服務

# CentOS/RHEL
yum install nfs-utils rpcbind -y

# Ubuntu/Debian
apt-get install nfs-kernel-server -y

2. 設定匯出目錄 /etc/exports

/tmp/php_sess/ 192.168.0.*(rw,sync,no_root_squash,no_subtree_check)

關鍵選項說明:

  • rw:讀寫權限
  • sync:同步寫入(資料安全優先)
  • no_root_squash:允許客戶端 root 權限寫入(Session 檔案通常由 www-data/apache 建立,視實際情況調整)
  • no_subtree_check:提升效能,減少子目錄檢查

3. 啟動並設定開機自啟

systemctl enable rpcbind nfs-server --now
exportfs -rv  # 重新匯出

第三階段:客戶端掛載 (192.168.0.2, 192.168.0.3)

# 安裝客戶端工具
yum install nfs-utils -y  # 或 apt-get install nfs-common

# 建立掛載點
mkdir -p /tmp/php_sess

# 測試掛載
mount -t nfs 192.168.0.1:/tmp/php_sess /tmp/php_sess

# 寫入 /etc/fstab 實現開機自動掛載
echo "192.168.0.1:/tmp/php_sess /tmp/php_sess nfs defaults,_netdev 0 0" >> /etc/fstab

第四階段:驗證與效能調優

1. 基本驗證

# 於任一客戶端建立測試檔案
echo "test" > /tmp/php_sess/test.txt

# 於其他客戶端確認可見
cat /tmp/php_sess/test.txt

2. PHP 設定同步

確認所有節點 php.ini 皆設定:

session.save_handler = files
session.save_path = "2;/tmp/php_sess"
session.gc_maxlifetime = 1440  # 視需求調整

重啟 PHP-FPM/Apache 後,使用瀏覽器開發者工具觀察 Session ID 是否在不同節點間保持一致。

3. 效能調優建議

  • 網路延遲:NFS 對延遲敏感,建議部署在同一 VPC/機房,使用萬兆網路。
  • async 模式:若能容忍極小機率資料遺失,可在 /etc/exports 改用 async 大幅提升寫入效能。
  • 快取機制:客戶端掛載加入 actimeo=1 減少屬性快取延遲:
    mount -o actimeo=1 192.168.0.1:/tmp/php_sess /tmp/php_sess
  • 監控指標:關注 iostat -x 中 await、svctm、NFS 執行緒數 (nfsstat -rc)。

常見坑點與替代方案

總結

NFS 方案優勢在於**零程式碼修改、成熟穩定、利用現有檔案系統語意**,適合中小型流量、運維資源有限的團隊。但隨著流量增長,NFS 的單點瓶頸、延遲敏感、鎖競爭問題會逐漸凸現。建議演進路徑:本地檔案 → NFS → Redis Cluster / Database (配合 session_set_save_handler)。無論選擇哪種方案,**Session ID 跨域共享 (cookie_domain) 與儲存後端高可用**始終是核心關鍵。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
問題原因對策
Session 檔案權限錯誤多節點 UID/GID 不一致統一 Apache/PHP-FPM 運行使用者 UID/GID,或使用 bindfs 映射
NFS 掛載點失聯導致 PHP hang 住預設 hard mount 會無限重試掛載參數加入 soft,timeo=10,retrans=3 快速失敗,並實作健康檢查自動摘除節點
單點故障NFS Server 掛掉全站 Session 失效部署 NFS HA (DRBD+Heartbeat/Corosync) 或改用 Redis/Memcached/Database 方案