摘要:方法銷毀大于給定的所有數(shù)據(jù),對本身擁有過期機制的系統(tǒng)如和而言,該方法可以留空。注意事項瀏覽器標(biāo)簽?zāi)_本執(zhí)行過程中,打開標(biāo)簽訪問同一個腳本,會被,直到執(zhí)行完畢。
概述
分布式session是實現(xiàn)分布式部署的前提, 當(dāng)前項目由于歷史原因未實現(xiàn)分布式session, 但是由于在kubernets中部署多個pod時, 負(fù)載均衡的調(diào)用鏈太長, 導(dǎo)致會話不能保持, 所以迫切需要分布式session.
實現(xiàn)方案 a. 修改配置文件php.ini直接在PHP中配置, 或者在代碼中集成
session.save_handler = redis session.save_path = "tcp://127.0.0.1:6379"b. 代碼中動態(tài)設(shè)置
ini_set("session.save_handler", "redis"); ini_set("session.save_path", "tcp://127.0.0.1:6379");c. 實現(xiàn)SessionHandlerInterface接口
php提供了SessionHandlerInterface接口, 按照此接口進(jìn)行implements, 即可完成session共享。
/** * @see http://php.net/manual/zh/class.sessionhandlerinterface.php */ SessionHandlerInterface { abstract public bool close ( void ) abstract public bool destroy ( string $session_id ) abstract public int gc ( int $maxlifetime ) abstract public bool open ( string $save_path , string $session_name ) abstract public string read ( string $session_id ) abstract public bool write ( string $session_id , string $session_data ) } /** * @see http://php.net/manual/zh/class.sessionhandler.php */ MySessionHandler implements SessionHandlerInterface , SessionIdInterface { public bool close ( void ) public string create_sid ( void ) public bool destroy ( string $session_id ) public int gc ( int $maxlifetime ) public bool open ( string $save_path , string $session_name ) public string read ( string $session_id ) public bool write ( string $session_id , string $session_data ) }
如上是PHP文檔中對此interface的描述, 下面介紹下迅速過一下涉及到的幾個方法:
方法 | 說明 | |
---|---|---|
open | 方法用于基于文件的session存儲系統(tǒng), 該方法中可不放置任何代碼,可以將其置為空方法。 | |
close | 和open 方法一樣,也可以被忽略,對大多數(shù)驅(qū)動而言都用不到該方法。 | |
read | 應(yīng)該返回與給定$sessionId, 相匹配的session數(shù)據(jù)的字符串版本。 | |
write | 應(yīng)該講給定$data 寫到持久化存儲系統(tǒng)相應(yīng)的$sessionId destroy | 從持久化存儲中移除 $sessionId 對應(yīng)的數(shù)據(jù)。 |
gc | 方法銷毀大于給定 $lifetime 的所有session數(shù)據(jù),對本身擁有過期機制的系統(tǒng)如 Memcached 和 Redis 而言,該方法可以留空。 |
實現(xiàn)完成后使用session_set_save_handler完成session驅(qū)動的注冊
$handler = new MySessionHandler(); session_set_save_handler($handler, true); // 下面這行代碼可以防止使用對象作為會話保存管理器時可能引發(fā)的非預(yù)期行為 register_shutdown_function("session_write_close"); session_start(); // 現(xiàn)在可以使用 $_SESSION 保存以及獲取數(shù)據(jù)了
Warning: 在腳本執(zhí)行完畢之后, PHP內(nèi)部會清除對象, 所以有可能不調(diào)用write和close回調(diào)函數(shù), 這樣可能會引發(fā)非預(yù)期的行為, 所以當(dāng)使用對象作為會話保存管理器時, 需要通過注冊 shutdown回調(diào)函數(shù)來規(guī)避風(fēng)險。通常,你可以通過調(diào)用register_shutdown_function()函數(shù)來注冊session_write_close()回調(diào)函數(shù)d. 自定義session驅(qū)動
可通過memcached、redis、db等實現(xiàn)分布式session,考慮先實現(xiàn)redis session驅(qū)動
我們知道一般情況下cookie中存儲著session id, 所以實現(xiàn)自定義session, 需要一些配置, 配置如下:
參數(shù) | 默認(rèn)值 | 選項 | 描述 |
---|---|---|---|
sess.driver | files | files/database/redis/memcached/custom | 使用的存儲 session 的驅(qū)動 |
sess.cookie_name | my_session | [A-Za-z_-] characters only | session cookie 的名稱 |
sess.expiration | 7200 (2 hours) | Time in seconds (integer) | 你希望 session 持續(xù)的秒數(shù) 如果你希望 session 不過期(直到瀏覽器關(guān)閉),將其設(shè)置為 0 |
sess.save_path | NULL | None | 指定存儲位置,取決于使用的存儲 session 的驅(qū)動 |
sess.time_to_update | 300 | Time in seconds (integer) | 該選項用于控制過多久將重新生成一個新 session ID 設(shè)置為 0 將禁用 session ID 的重新生成 |
sess.regenerate_destroy | FALSE | TRUE/FALSE (boolean) | 當(dāng)自動重新生成 session ID 時,是否銷毀老的 session ID 對應(yīng)的數(shù)據(jù) 如果設(shè)置為 FALSE ,數(shù)據(jù)之后將自動被垃圾回收器刪除 |
使用時, $_SESSION 的操作改為 RedisSession 類操作.
例如:
$_SESSION["aa"] = 123; 改為 RedisSession::set("aa", 123);
echo $_SESSION["aa"]; 改為 echo RedisSession::get("aa");
Warning: 由于Redis沒有鎖機制, 這個驅(qū)動的鎖是通過一個保持300s的值來模擬的。
Redis 是一種存儲引擎,通常用于緩存,并由于他的高性能而流行起來,這可能也正是你使用 Redis 驅(qū)動的原因。
缺點是它并不像關(guān)系型數(shù)據(jù)庫那樣普遍,需要你的系統(tǒng)中安裝了 phpredis 這個 PHP 擴展,它并不是 PHP 程序自帶的。 可能的情況是,你使用 Redis 驅(qū)動的原因是你已經(jīng)非常熟悉 Redis 了并且你使用它還有其他的目的。
當(dāng)然不想安裝phpredis客戶端時, 能承受一定的性能損失, 可使用predis包
https://github.com/nrk/predis
和文件驅(qū)動和數(shù)據(jù)庫驅(qū)動一樣,你必須通過 sess.save_path 參數(shù)來配置存儲 session 的位置。 這里的格式有些不同,同時也要復(fù)雜一點,這在 phpredis 擴展的 README 文件中有很好的解釋,鏈接如下:
https://github.com/phpredis/p...
Warning: 這里的 Session 類并沒有真的用到 "redis" 的 session.save_handler , 只是 采用了它的路徑的格式而已。
!
注意事項 a. 瀏覽器A標(biāo)簽?zāi)_本執(zhí)行過程中,打開B標(biāo)簽訪問同一個腳本,會被pending,直到A執(zhí)行完畢。原因該腳本執(zhí)行了session_start(),而php session_start()后對該session的寫入是排他的,只有當(dāng)腳本執(zhí)行結(jié)束或顯式執(zhí)行session_destroy()才能釋放session文件鎖。b. 自定義session驅(qū)動并不是那么簡單, 需要用到很多知識來正確的實現(xiàn)它。
你不僅要知道session一般的工作原理,而且要知道它在PHP中如何實現(xiàn)的,還要知道它的內(nèi)部存儲機制是如何工作的,如何去處理并發(fā),如何去避免死鎖(不能去掉鎖),以及如何處理潛在的安全問題
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/29259.html
摘要:每次消費時,如果顧客出示這張卡片,則此次消費就會與以前或以后的消費相聯(lián)系起來。由于可以被人為的禁止,必須有其他機制以便在被禁止時仍然能夠把傳遞回服務(wù)器。 github 地址:戳這里 session 概念 指一類用來在客戶端與服務(wù)器之間保持狀態(tài)的解決方案 這種解決方案的存儲結(jié)構(gòu) 特點 由于 Session 是以文本文件形式存儲在服務(wù)器端的,所以不怕客戶端修改 Session 內(nèi)容。...
摘要:前言最近看了一些同學(xué)的面經(jīng),發(fā)現(xiàn)無論什么技術(shù)崗位,還是會問到和的區(qū)別。所有學(xué)技術(shù)的同學(xué)都知道和函數(shù)怎么用,知道和的區(qū)別就是是儲存在服務(wù)端的,是存儲在瀏覽器的。的誕生是為了能讓無狀態(tài)的報文帶上一些特殊的數(shù)據(jù),讓服務(wù)端能夠辨識請求的身份。 1 前言 最近看了一些同學(xué)的面經(jīng),發(fā)現(xiàn)無論什么技術(shù)崗位,還是會問到 Session 和 Cookie 的區(qū)別。 所有學(xué)技術(shù)的同學(xué)都知道 Session ...
摘要:通過瀏覽器的,可以看到此次會話的請求內(nèi)容和響應(yīng)內(nèi)容。是協(xié)議的一部分。真實的產(chǎn)品,一般是創(chuàng)建一個保證唯一的,不易猜測出來的字符串。因此需要數(shù)據(jù)持久化的多提供者的方案。 使用過幾種Web App開發(fā)語言和框架,都會接觸到Session的概念。即使是一個簡單站點訪問計數(shù)的功能,也常常使用Session來實現(xiàn)的。其他常用的領(lǐng)域還有購物車,登錄用戶等。但是,對Session一直是一知半解,知其然...
摘要:服務(wù)器檢查該,以此來辨認(rèn)用戶狀態(tài)。五下的相關(guān)應(yīng)用應(yīng)用在中配置如下配置項用于設(shè)置存儲方式,默認(rèn)是,即存儲在文件中,該文件位于配置項配置的路徑,即。配置項用于設(shè)置有效期,默認(rèn)為分鐘。配置項用于配置數(shù)據(jù)是否加密。 一、cookie的由來 ??當(dāng)用戶訪問某網(wǎng)站時,web服務(wù)器會將部分信息保存到本地計算機上,當(dāng)用戶再次關(guān)顧該網(wǎng)站時,服務(wù)器會去查看用戶是否登錄過該網(wǎng)站,如果登錄過,就會將這些記錄在...
閱讀 3339·2023-04-25 18:03
閱讀 1171·2021-11-15 11:38
閱讀 5657·2021-10-25 09:45
閱讀 863·2021-09-24 09:48
閱讀 2337·2021-09-22 15:34
閱讀 1761·2019-08-30 15:44
閱讀 2698·2019-08-30 13:12
閱讀 623·2019-08-29 16:05