這是我們在過去幾周面臨的問題。PHP中的隨機會話數據丟失
1 /我們的設置
- PHP 5.4 + MySQL的
- 2專用服務器使用分佈式緩存
- 3應用程序,負載平衡
- 會話在2個服務器之間複製這些運行服務器:
- 一個自定義開發的應用程序,使用默認的PHP會話設置
- 另一個定製developped應用程序,使用不同的會話設置(cookie名稱,路徑)
- 一個WordPress的CMS
2 /問題
,我們第一次出現的問題應用。
我們的一些用戶報告說,他們有時會在幾分鐘後斷開連接(當會話設置爲最後3小時時)。它可能會在同一天發生幾次,然後幾天沒有斷開,但問題總是會回來。 到目前爲止,受影響的用戶比例很小,但我希望在它「傳播」給其他用戶之前解決此問題。
這個問題似乎在應用程序的不同地方發生,但我們已經確定了3個scenarii大多數錯誤的發生:
- 一些涉及提交表單($ _SESSION變量修改)
- 其他只是涉及打開一個彈出頁面,沒有修改會話數據
我們試圖重現用戶描述的不同情景:有時我們能夠,但大多數時候我們不能有任何公關這使得它很難調試。
其他說明:
- 問題是最近,這個應用程序已經運行了數年沒有任何問題。
- 它似乎不涉及我們的服務器負載,因爲問題仍然發生在暑假期間,當我們的交通不便時
- 它一次隻影響一個會話/用戶:所有其他用戶登錄同時當斷開時不會遇到此問題上的所有不同的瀏覽器
- 問題發生(IE,火狐,Chrome)
3 /技術分析
中,用戶重定向添加到頁面「您的會話已過期,或者您無權查看」。當這個頁面被加載時,我們得到一個帶有$ _SESSION變量轉儲的技術郵件。
當會話以正常方式到期時,我們得到的電子郵件顯示$ _SESSION變量爲空(正常行爲)。 當意外的斷開連接發生時,有趣的是$ _SESSION不完全是空的:在數組包含的〜20個元素中,只剩下一個(總是相同)。
所以這意味着會話沒有過期,但沒有足夠的數據來「標識」用戶,因此顯示「無權限」頁面。作爲發生這種情況的確認,我們可以檢查memcached,此會話仍保留一些數據。
這些都是潛在的問題會導致到目前爲止,我們已經確定,而我們所做的,以排除他們:
- Memcached的指示70等80%的自由空間之間,所以我們不認爲這是問題。
- 我們刪除了Memcached並返回使用會話文件的NFS共享目錄:問題實際上變得更糟。這將指向一個應用程序錯誤,因爲NFS寫入數據較慢,會話丟失會更頻繁地發生。
- 我們瀏覽了所有討論PHP會話數據丟失的論壇(包括SO),並相應地檢查了我們的代碼。代碼庫很大,但我們使用自動化工具和腳本來避免丟失文件。
- session_start()在每個頁面的開頭被調用。
- exit()時每頭後調用(「位置...」)
- register_globals被關閉
- 我們已經測試了我們2個其他應用程序和有問題的一個之間可能interractions,雖然他們不不共享任何代碼,數據庫或會話處理。沒有在那裏確定。
- 我們分析了斷開連接時間的訪問日誌,以檢查行爲模式:這裏也沒有運氣。
所以我們不知道是什麼原因導致這個問題,因爲它似乎是隨機發生的,所以我的問題是:
- 問題可能來自於我們的代碼:難道我們錯過了什麼檢查?這些解決方案似乎不太可能,因爲代碼大部分時間都適用於所有用戶,但我仍在考慮這一點。
- 問題可能來自另一個應用程序/進程,它將「清空」部分會話變量數組。我們也檢查了其他應用程序的代碼,但沒有發現任何可能導致此問題的內容。 如果另一個進程正在這樣做,爲什麼它只會清空一些會話而不是所有會話?
感謝您的幫助。
問題的出現是否與PHP升級一致? – 2014-09-03 11:27:56
我碰到過這個問題的機會......我們在Memcached服務器上出現隨機會話丟失的問題。 PHP應用程序,運行PHP 5.3的兩臺服務器負載均衡。我們還有一個專門的數據庫服務器,安裝了Memcached。某些用戶的會話在登錄後2分鐘過期。其他人可以整天無需註銷。 – 2014-09-03 11:34:39
您是否考慮過不使用Memcached,而是在您的服務器之間使用共享會話目錄,並且只使用基於PHP的本地文件會話。假設你使用php.ini來定義memcached會話,這將是任何簡單的切換,只需創建一個共享卷,將其掛載到所有服務器(fstab進行自動掛載)並切換session.save_path =「/ path/to/mount」 ,如果問題仍然存在,它可能是您的應用程序,否則可能是PHP/Memcache不能很好地一起玩。 – 2014-09-03 11:36:40