您好,登錄后才能下訂單哦!
下文給大家帶來session共享、工作原理及問題解決方案,希望能夠給大家在實際運用中帶來一定的幫助,負載均衡涉及的東西比較多,理論也不多,網上有很多書籍,今天我們就用億速云在行業內累計的經驗來做一個解答。
稍大一些的網站,通常都會有好幾個云服務器,每個服務器運行著不同功能的模塊,使用不同的二級域名,而一個整體性強的網站,用戶系統是統一的,即一套用戶名、密碼在整個網站的各個模塊中都是可以登錄使用的。各個服務器共享用戶數據是比較容易實現的,只需要在后端放個數據庫服務器,各個服務器通過統一接口對用戶數據進行訪問即可。但還存在一個問題,就是用戶在這個服務器登錄之后,進入另一個服務器的別的模塊時,仍然需要重新登錄,這就是一次登錄,全部通行的問題,映射到技術上,其實就是各個服務器之間如何實現共享 SESSION 數據的問題。
在解決問題之前,先來了解一下 PHP SESSION 的工作原理。在客戶端(如瀏覽器)登錄網站時,被訪問的 PHP 頁面可以使用 session_start() 打開 SESSION,這樣就會產生客戶端的唯一標識 SESSION ID(此 ID 可通過函數 session_id() 獲取/設置)。SESSION ID 可以通過兩種方式保留在客戶端,使得請求不同的頁面時,PHP 程序可以獲知客戶端的 SESSION ID;一種是將 SESSION ID 自動加入到 GET 的 URL 中,或者 POST 的表單中,默認情況下,變量名為 PHPSESSID;另一種是通過 COOKIE,將 SESSION ID 保存在 COOKIE 中,默認情況下,這個 COOKIE 的名字為 PHPSESSID。這里我們主要以 COOKIE 方式進行說明,因為應用比較廣泛。
服務端通過客戶端傳遞的session_id區分用戶,用來標記用戶的登錄狀態。
用戶再次發送請求的時候,把服務端返回的session_id通過cookie[或者URL傳參]的形式傳遞到服務端,這樣服務端就可以區分出來具體操作的用戶。
1.不使用session,換作cookie
把session改成cookie,就能避開session的一些弊端。【安全性較低】
2.數據庫記錄下session信息
使用數據庫記錄session信息,session的使用頻率比較高,如果存在數據庫中,頻繁的讀取會對數據庫產生較大的壓力,網站性能瓶頸一般都存在數據庫.
3.負載均衡的時候使用ip_hash算法進行分發
使用ip_hash可能會導致某一臺服務器負載較大。如果某段時間內服務器進入了很多固定IP代理的請求 [代理] ,如果代理IP的負載過高就會導致ip_hash對應的服務器負載壓力過大,這樣ip_hash就失去了負載均衡的作用了。
4.對session文件進行同步
使用同步工具對session文件進行同步,保證負載服務器的session文件都是一致的,這種做法雖然可以解決session共享的問題,同樣的內容會存在多個服務器上,而且部分服務器存在的session文件可能從開始到結束完全沒有使用到,浪費了服務器的資源。 【rsync,inotify-tools等】
5.使用memcache或者redis保存session信息 [建議]
相比文件取信息,從內存取數據速度要快很多,而且在多個服務器需要共用 session 時會比較方便,將這些服務器都配置成使用同一組 memcached 服務器就可以,減少了額外的工作量。其缺點是 session 數據都保存在 memory 中,一旦宕機,數據將會丟失。但對 session 數據來說并不是嚴重的問題。
1、session默認存儲是php.ini中配置的
//session存儲方式
session.save_handler = files
//session保存路徑 N表示按照分級存儲
session.save_path = "N;/path"
注:session.save_path = "2;/data/session_tmp"代表將session文件分成兩級存放,即/data/session_tmp/4/b /sess_4b1e384ad74619bd212e236e52a5a174If,取前兩位字符,但是php并不生成目錄,需要自己手工生成。
//session保存的目錄
session.save_path = "d:/wamp/tmp" php自帶函數session_save_path
//是否自動開啟session
session.auto_start = 0
2、設置session保存方式為redis
(1) 修改完成之后重啟php-fpm,nginx改php.ini配置文件
session.save_handler = redis
session.save_path = “tcp://127.0.0.1:6379″
(2) 通過ini_set設置
ini_set(“session.save_handler”,”redis”);
ini_set(“session.save_path”,”tcp://127.0.0.1:6379″);
有密碼設置
ini_set(“session.save_path”,”tcp://127.0.0.1:6379?auth=redisauthkey″);
(3) 具體實現
<?php
//如果未修改php.ini下面兩行注釋去掉
//ini_set('session.save_handler', 'redis');
//ini_set('session.save_path', 'tcp://127.0.0.1:6379');
session_start();
$_SESSION['sessionid'] = 'this is session content!';
echo $_SESSION['sessionid'];
echo '<br/>';
$redis = new redis();
$redis->connect('127.0.0.1', 6379);
$redis->auth( ‘redisauthkey’ );
//redis用session_id作為key并且是以string的形式存儲
echo $redis->get('PHPREDIS_SESSION:' . session_id());
?>
3、通過session_id建立自己的一套session機制
借助session_id建議一套自己的機制,原理可以參考session保存機制。
用戶第一次請求時候,給用戶下發session_id。
之后請求都要帶上session
好處就是:把自己的一套session機制抽象為類,如果之后session不存在redis,后期可以直接通過修改類文件解決問題。
看了以上關于session共享、工作原理及問題解決方案,如果大家還有什么地方需要了解的可以在億速云行業資訊里查找自己感興趣的或者找我們的專業技術工程師解答的,億速云技術工程師在行業內擁有十幾年的經驗了。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。