標籤:伺服器 情況 const life star view 一個 file foo
cookie和session有什麼區別?這是一個很基礎的知識點,大家可能都知道一個大概:cookie是存在用戶端的,session是儲存在服務端,cookie和session用來驗證識別使用者的登入狀態,常見適用情境:使用者登入,使用者購物車資料等。偶然一次開發中遇到這些基礎的知識,還要去baidu一下,今天就做一個完整的記錄,便於以後查閱。
1.基礎概念
cookie儲存在用戶端電腦中一般在:C:\Users\***\AppData\Local\Microsoft\Windows\Temporary Internet Files(檔案夾隱藏了),可以到自己電腦的IE設定裡面去查看,直接開啟。
我們建立一個設定cookie和session的簡單檔案實驗一下:
<?php$value = "my cookie value";// 發送一個簡單的 cookiesetcookie("TestCookie",$value,time()+3600,"/","127.0.0.1");//setcookie("TestCookie",$value, time()+3600*24);echo "setcookie Success!<br />";session_start();//views計數存在session裡面if(isset($_SESSION[‘views‘])) $_SESSION[‘views‘]=$_SESSION[‘views‘]+1;else $_SESSION[‘views‘]=1;echo "Views=". $_SESSION[‘views‘]."<br />";echo session_id()."<br />";print_r($_SESSION);echo "setsession Success!";?>
訪問下,使用調試工具看看cookie:
ok,可以看見設定cookie成功了,而且在服務端也產生了相應的 session,服務端儲存session的位置一般在php.ini中可以找到:
找到相應的目錄下可以看到:session檔案以sess_***********************格式儲存,根據上面的PHPSESSID可以對應到所在的session檔案為:開啟看一下,和我們答應出來的session內容進行對比:
很明顯,這裡的內容就是$_SESSION中的內容。cookie和session整個互動過程用一張圖來表示:
或者更詳細一點:
在日常高並發,分布式的系統中經常會遇到一個問題,高並發請求對伺服器負載壓力過大,然後我們的方案是做負載平衡,使用nginx做反向 Proxy,多台主機(tomcat或者Apache)來做後端響應。這裡,問題就來了,多台伺服器的時候,不同的請求分發到不同的伺服器上,產生了不同的session,如果是儲存在記憶體或者檔案中,那麼就無法保持同一個使用者的登入狀態了,我們如何解決呢?
這裡要根據我們系統的實際情況進行選擇:
A.如果不是高並發,使用者很少,對session的操作不是很頻繁,我們可以選擇將session儲存在mysql資料庫中
B.如果是對效能有一定的要求,且操作頻繁,我們可以選用k/v非結構化資料庫,如:redis
若使用php語言,以上兩種方案都需要修改php.ini中session.save_handler = files 中的files改為User
關於redis 安裝和php-redis擴充的安裝請點這裡:windows下 redis和php-redis安裝
這裡我們給一份PHP的參考代碼:php中有一個session_set_save_handler()函數,可以自訂對session的操作方法,主要的幾個操作,開啟,寫入,讀取,刪除分別對應到函數的6個參數。bool session_set_save_handler ( callable $open
, callable $close
, callable $read
, callable $write
, callable $destroy
, callable $gc
),
session_set_save_handler
函數各參數作用如下表
參 數 |
描述 |
open |
當session開啟時調用此函數。接收兩個參數,第一個參數是保持session的路徑,第二個參數是session的名字 |
close |
當session操作完成時調用此函數。不接收參數。 |
read |
以session ID作為參數。通過session ID從資料存放區方中取得資料,並返回此資料。如果資料為空白,可以返回一個Null 字元串。此函數在調用session_start 前被觸發 |
write |
當資料存放區時調用。有兩個參數,一個是session ID,另外一個是session的資料 |
destroy |
當調用session_destroy 函數時觸發destroy函數。只有一個參數 session ID |
gc |
當php執行session記憶體回收機制時觸發 |
同樣的使用前需要到php.ini中進行配置一下。
session管理操作類:sessionredisManage.php
<?phpclass SessionRedisManage { private $redis; private $sessionSavePath; private $sessionName; private $sessionExpireTime = 1800; // session的有效期間,設定為1800秒 /** * 建構函式 */ public function __construct() { $this->redis = new Redis(); // 建立一個redis用戶端對象 $this->redis->connect(‘127.0.0.1‘, 6379) || die(‘串連redis伺服器失敗!‘); // 串連redis伺服器 $this->redis->auth(‘foobared‘); // 密碼驗證 $this->redis->select(0); // 選擇0號資料庫 $retval = session_set_save_handler( array($this, "open"), array($this, "close"), array($this, "read"), array($this, "write"), array($this, "destroy"), array($this, "gc") ); session_start(); // 啟動session } public function open($patn, $name) { return true; } public function close() { return true; } public function read($id) { $value = $this->redis->get($id); if ($value) { return $value; } else { return ‘‘; } } public function write($id, $data) { if ($this->redis->set($id, $data)) { $this->redis->expire($id, $this->sessionExpireTime); return true; } else { return false; } } public function destory($id) { if ($this->redis->delete($id)) { return true; } else { return false; } } public function gc($maxlifetime) { return true; } public function __destruct() { session_write_close(); }}?>
注意:在上面代碼中的write方法中,以sessionid作為鍵名,把session的值作為value儲存到redis中,在read方法中,以sessionid作為鍵名key,從redis中擷取值返回。而在destroy回呼函數中,則以sessionid作為key 從redis伺服器中刪除對應的session資料。
然後,建立session_set.php和session_get.php來設定,擷取session值,我們測試一下。
session_set.php
<?phprequire ‘SessionManager.php‘;new SessionManager(); // 執行個體化對象,開啟自訂的session儲存機制$_SESSION[‘username‘] = ‘masonzhang‘; // 寫入sessionecho "session_set success!";?>
session_get.php
<?phprequire ‘SessionManager.php‘;new SessionManager(); // 執行個體化對象,開啟自訂的session儲存機制echo $_SESSION[‘username‘]; // 擷取指定的session變數?>
測試:先訪問session_set.php
看一下redis資料庫:
然後訪問session_get.php
經測試,不同頁簽均可擷取到username,說明可以跨頁面訪問。
到這裡我們這個方案能實現nginx+php+redis的session共用了。
分享一個JAVA版本的,大家一起學習:
http://blog.csdn.net/xlgen157387/article/details/52024139
一篇文章讓你深透理解cookie和session,附帶分布式WEB系統redis共用session方案