首页 php教程 php手册 深入Memcache的Session数据的多服务器共享详解

深入Memcache的Session数据的多服务器共享详解

Jun 13, 2016 am 11:49 AM
memcache session 介绍 共享 数据 服务器 深入 相关 详解

一相关介绍
1.memcache + memcache的多服务器数据共享的介绍
,请参见http://www.guigui8.com/index.php/archives/206.html
2.session机制:
session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。
当程序需要为某个客户端的请求创建一个session的时候,服务器首先检查这个客户端的请求里是否已包含了一个session标识- 称为sessionid,如果已包含一个sessionid则说明以前已经为此客户端创建过session,服务器就按照sessionid把这个session检索出来使用(如果检索不到,可能会新建一个),如果客户端请求不包含sessionid,则为此客户端创建一个session并且生成一个与此session相关联的sessionid,sessionid的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个sessionid将被在本次响应中返回给客户端保存。

保存这个sessionid的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发挥给服务器。

一般这个cookie的名字都是类似于SEEESIONID,而。比如weblogic对于web应用程序生成的cookie,PHPSESSID=ByOK3vjFD75aPnrF3K2HmdnV6QZcEbzWoWiBYEnLerj,它的名字就是PHPSESSID。

二动机
在实际web生产环境中,一个应用系统,往往将不同的业务应用分布到不同服务器上进行处理。
当跟踪当前在线用户信息时,如果是同一个主域名时,可以用全域cookie处理相关数据的共享问题;如果是在不同主域下,则可以通过观察者模式的中心话概念解决相应问题,通过这种概念延伸出的解决方案有很多,而今天我所要讲的,是前一种,通过memcache的多服务器数据共享技术来模拟session,以进行对当前在线用户数据的多服务器共享。
关于多服务器统一session信息,要求如下:
1.能够在memcached规定的几台服务器上,保存session信息(通过前面介绍的memcache的多服务器数据共享);
2.能够象zend定义的session_start()前,通过session_id($sessid)那样,自定义session_id的值。
3.能方便的在系统运行时,切换memcached存储的session信息和 用文件存储的session信息的操作。

三代码
实现方式很简单,通过memcache来模拟session机制,只是利用memcache将存储媒介换成共享服务器的内存,以达到多台分布式部署的服务器共享session信息的目的。而调用的接口,与zend提供的session操作函数相区别,所以可以方便的在memcache和文件的session信息操作建切换。
以下代码,已经过多次实际测试,能达到以上功能需求。先贴下面了:

复制代码 代码如下:


/**
 *=---------------------------------------------------------------------------=
 *                         MemcacheSession.class.php
 *=---------------------------------------------------------------------------=
 *
 * 实现基于Memcache存储的 Session 功能
 *  (模拟session机制,只是利用memcache将存储媒介换成共享服务器的内存)
 *
 * 缺点:暂时没有引入不同主域的session共享机制的实现策略。即只支持同主域下的实现。
 *
 * Copyright(c) 2008 by guigui. All rights reserved.
 * @author guigui
 * @version $Id: MemcacheSession.class.php, v 1.0 2008/12/22 $
 * @package systen
 * @link http://www.guigui8.com
 */

 
/**
 * class MemcacheSession
 *
 * 1. 设置客户端的Cookie来保存SessionID
 * 2. 把用户的数据保存在服务器端,通过Cookie中的Session Id来确定一个数据是否是用户的
 */
class MemcacheSession
{
   // {{{ 类成员属性定义
   public  $memObject          = null;      //memcache操作对象句柄
   private $_sessId            = '';
   private $_sessKeyPrefix     = 'sess_';
   private $_sessExpireTime    = 86400;  
   private $_cookieDomain      = '.guigui8.com';   //全域cookie域名
   private $_cookieName        = '_PROJECT_MEMCACHE_SESS';
   private $_cookieExpireTime  = '';   

   private $_memServers        = array('192.168.0.3' => 11211, '192.168.0.4' => 11211);
   private $_sessContainer     = array();     //当前用户的session信息
   private static $_instance   = null;      //本类单例对象
   // }}}

 
   /**
    * 单例对象获取的静态方法。
 * (可以顺便提供memcache信息存储的服务器参数)
    *
    * @param string $host   - memcache数据存储的服务器ip
    * @param integer $port  - memcache数据存储的服务器端口号
    * @param bool $isInit   - 是否实例化对象的时候启动Session
    */
   public static function getInstance($host='', $port=11211, $isInit = true) {
     if (null === self::$_instance) {
      self::$_instance = new self($host, $port, $isInit);
     }
     return self::$_instance;
   }

   /**
    * 构造函数
    *
    * @param bool $isInit - 是否实例化对象的时候启动Session
    */
   private function __construct($host='', $port=11211, $isInit = false){
       !empty($host) && $this->_memServers = array(trim($host) => $port);
       $isInit && $this->start();
   }

   /**
  *=-----------------------------------------------------------------------=
  *=-----------------------------------------------------------------------=
 *      Public Methods
  *=-----------------------------------------------------------------------=
  *=-----------------------------------------------------------------------=
  */

   /**
    * 启动Session操作
    *
    * @param int $expireTime - Session失效时间,缺省是0,当浏览器关闭的时候失效, 该值单位是秒
    */
   public function start($expireTime = 0){
       $_sessId = $_COOKIE[$this->_cookieName];
       if (!$_sessId){
           $this->_sessId = $this->_getId();
           $this->_cookieExpireTime = ($expireTime > 0) ? time() + $expireTime : 0;
           setcookie($this->_cookieName, $this->_sessId, $this->_cookieExpireTime, "/", $this->_cookieDomain);
           $this->_initMemcacheObj();

           $this->_sessContainer = array();
           $this->_saveSession();
       } else {
           $this->_sessId = $_sessId;
           $this->_sessContainer = $this->_getSession($_sessId);
       }       
   }

   /**
    * setSessId
    *
    * 自定义的session id,通常没有必要经过cookie操作处理的(所以省略了cookie记录session_id)
    *
    * @param string $sess_id
    * @return boolean
    */
   public function setSessId($sess_id){
       $_sessId = trim($sess_id);
       if (!$_sessId){
           return false;
       } else {
           $this->_sessId = $_sessId;
           $this->_sessContainer = $this->_getSession($_sessId);
       }       
   }

   /**
    * 判断某个Session变量是否注册
    *
    * @param string $varName -
    * @return bool 存在返回true, 不存在返回false
    */
   public function isRegistered($varName){
       if (!isset($this->_sessContainer[$varName])){
           return false;
       }
       return true;
   }   

   /**
    * 注册一个Session变量
    *
    * @param string $varName - 需要注册成Session的变量名
    * @param mixed $varValue - 注册成Session变量的值
    * @return bool - 该变量名已经存在返回false, 注册成功返回true
    */
   public function set($varName, $varValue){
       $this->_sessContainer[$varName] = $varValue;
       $this->_saveSession();
       return true;
   }

   /**
    * 获取一个已注册的Session变量值
    *
    * @param string $varName - Session变量的名称
    * @return mixed - 不存在的变量返回false, 存在变量返回变量值
    */
   public function get($varName){
       if (!isset($this->_sessContainer[$varName])){
           return false;
       }
       return $this->_sessContainer[$varName];
   }   

   /**
    * 销毁一个已注册的Session变量
    *
    * @param string $varName - 需要销毁的Session变量名
    * @return bool 销毁成功返回true
    */
   public function delete($varName){
       unset($this->_sessContainer[$varName]);
       $this->_saveSession();
       return true;
   }

   /**
    * 销毁所有已经注册的Session变量
    *
    * @return 销毁成功返回true
    */
   public function destroy(){
       $this->_sessContainer = array();
       $this->_saveSession();
       return true;   
   }

 
   /**
    * 获取所有Session变量
    *
    * @return array - 返回所有已注册的Session变量值
    */
   public function getAll(){
       return $this->_sessContainer;
   }

   /**
    * 获取当前的Session ID
    *
    * @return string 获取的SessionID
    */
   public function getSid(){
       return $this->_sessId;
   }

   /**
    * 获取Memcache的服务器信息
    *
    * @return array Memcache配置数组信息
    */
   public function getMemServers(){
       return $this->_memServers;
   }

   /**
    * 设置Memcache的服务器信息
    *
    * @param string $host - Memcache服务器的IP
    * @param int $port - Memcache服务器的端口
    */
   public function setMemServers($arr){
       $this->_memServers = $arr;
   }   

   /**
    * 添加Memcache服务器
    *
    * @param string $host - Memcache服务器的IP
    * @param int $port - Memcache服务器的端口
    */
   public function addMemServer($host, $port){
       $this->_memServers[trim($host)] = trim($port);
       $this->memObject->addServer($host, $port);
   }  

   /**
    * 移除Memcache服务器(注意,这个只是移除配置,并不能实际从memcached的连接池移除)
    *
    * @param string $host - Memcache服务器的IP
    * @param int $port - Memcache服务器的端口
    */
   public function removeMemServer($host){
  unset($this->_memServers[trim($host)]);
   }  

   /**
  *=-----------------------------------------------------------------------=
  *=-----------------------------------------------------------------------=
 *      Private Methods
  *=-----------------------------------------------------------------------=
  *=-----------------------------------------------------------------------=
  */

   /**
    * 生成一个Session ID
    *
    * @return string 返回一个32位的Session ID
    */
   private function _getId(){
       return md5(uniqid(microtime()));
   }

   /**
    * 获取一个保存在Memcache的Session Key
    *
    * @param string $_sessId - 是否指定Session ID
    * @return string 获取到的Session Key
    */
   private function _getSessKey($_sessId = ''){
       $sessKey = ($_sessId == '') ? $this->_sessKeyPrefix.$this->_sessId : $this->_sessKeyPrefix.$_sessId;
       return $sessKey;
   }   
   /**
    * 检查保存Session数据的路径是否存在
    *
    * @return bool 成功返回true
    */
   private function _initMemcacheObj(){
       if (!class_exists('Memcache') || !function_exists('memcache_connect')){
           $this->_showMessage('Failed: Memcache extension not install, please from http://pecl.php.net download and install');
       }       
       if ($this->memObject && is_object($this->memObject)){
           return true;
       }
       $this->memObject = new Memcache;
       if (!empty($this->_memServers)) {
          foreach ($this->_memServers as $_host => $_port) {
            $this->memObject->addServer($_host, $_port);
        }
       }

       return true;
   }

   /**
    * 获取Session文件中的数据
    *
    * @param string $_sessId - 需要获取Session数据的SessionId
    * @return unknown
    */
   private function _getSession($_sessId = ''){
       $this->_initMemcacheObj();
       $sessKey = $this->_getSessKey($_sessId);
       $sessData = $this->memObject->get($sessKey);
       if (!is_array($sessData) || empty($sessData)){
         //this must be $_COOKIE['__SessHandler'] error!
         return array();
       }
       return $sessData;
   }

   /**
    * 把当前的Session数据保存到Memcache
    *
    * @param string $_sessId - Session ID
    * @return 成功返回true
    */
   private function _saveSession($_sessId = ''){
       $this->_initMemcacheObj();
       $sessKey = $this->_getSessKey($_sessId);

       if (empty($this->_sessContainer)){
           $ret = @$this->memObject->set($sessKey, $this->_sessContainer, false, $this->_sessExpireTime);
       }else{
           $ret = @$this->memObject->replace($sessKey, $this->_sessContainer, false, $this->_sessExpireTime);
       }

       if (!$ret){
           $this->_showMessage('Failed: Save sessiont data failed, please check memcache server');
       }
       return true;
   }

   /**
    * 显示提示信息
    *
    * @param string $strMessage - 需要显示的信息内容
    * @param bool $isFailed - 是否是失败信息, 缺省是true
    */
   private function _showMessage($strMessage, $isFailed = true){
     return;
       if ($isFailed){
           echo ($strMessage);
       }
       echo $strMessage;
   }   


四应用
1.本地session存储,与原始session操作方式一样,没有任何改变。如:

复制代码 代码如下:


session_start();
$_SESSION['file_session_info']= '本地文件保存的session信息'; //本地文件保存的session


2.memcache共享服务器的session存储

复制代码 代码如下:


$mem= MemcacheSession::getInstance('192.168.0.4', 11211);
$mem->addMemServer('192.168.0.4',11211);
$mem->addMemServer('192.168.0.5',11211);
//如果cookie功能不可用,则根据其他参数传递的唯一信息,设置映射为session_id
if(1) {
$sn= '838ece1033bf7c7468e873e79ba2a3ec';
$mem->setSessId($sn);
}
$mem->set('name','guigui');  //多台memcache服务器共享的session
$mem->set('addr','wuhan');  //多台memcache服务器共享的session
//$mem->destroy();


3.分别获取本地和memcache存储的session信息

复制代码 代码如下:


$addr= $mem->get('addr');
$_MEM_SESSION= $mem->getAll();
echo"


localhost file session:";
var_dump($_SESSION);
echo"
memcache session:";
var_dump($_MEM_SESSION);
//$res= $mem->delete('name');

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

开源!超越ZoeDepth! DepthFM:快速且精确的单目深度估计! 开源!超越ZoeDepth! DepthFM:快速且精确的单目深度估计! Apr 03, 2024 pm 12:04 PM

0.这篇文章干了啥?提出了DepthFM:一个多功能且快速的最先进的生成式单目深度估计模型。除了传统的深度估计任务外,DepthFM还展示了在深度修复等下游任务中的最先进能力。DepthFM效率高,可以在少数推理步骤内合成深度图。下面一起来阅读一下这项工作~1.论文信息标题:DepthFM:FastMonocularDepthEstimationwithFlowMatching作者:MingGui,JohannesS.Fischer,UlrichPrestel,PingchuanMa,Dmytr

谷歌狂喜:JAX性能超越Pytorch、TensorFlow!或成GPU推理训练最快选择 谷歌狂喜:JAX性能超越Pytorch、TensorFlow!或成GPU推理训练最快选择 Apr 01, 2024 pm 07:46 PM

谷歌力推的JAX在最近的基准测试中性能已经超过Pytorch和TensorFlow,7项指标排名第一。而且测试并不是在JAX性能表现最好的TPU上完成的。虽然现在在开发者中,Pytorch依然比Tensorflow更受欢迎。但未来,也许有更多的大模型会基于JAX平台进行训练和运行。模型最近,Keras团队为三个后端(TensorFlow、JAX、PyTorch)与原生PyTorch实现以及搭配TensorFlow的Keras2进行了基准测试。首先,他们为生成式和非生成式人工智能任务选择了一组主流

iPhone上的蜂窝数据互联网速度慢:修复 iPhone上的蜂窝数据互联网速度慢:修复 May 03, 2024 pm 09:01 PM

在iPhone上面临滞后,缓慢的移动数据连接?通常,手机上蜂窝互联网的强度取决于几个因素,例如区域、蜂窝网络类型、漫游类型等。您可以采取一些措施来获得更快、更可靠的蜂窝互联网连接。修复1–强制重启iPhone有时,强制重启设备只会重置许多内容,包括蜂窝网络连接。步骤1–只需按一次音量调高键并松开即可。接下来,按降低音量键并再次释放它。步骤2–该过程的下一部分是按住右侧的按钮。让iPhone完成重启。启用蜂窝数据并检查网络速度。再次检查修复2–更改数据模式虽然5G提供了更好的网络速度,但在信号较弱

超级智能体生命力觉醒!可自我更新的AI来了,妈妈再也不用担心数据瓶颈难题 超级智能体生命力觉醒!可自我更新的AI来了,妈妈再也不用担心数据瓶颈难题 Apr 29, 2024 pm 06:55 PM

哭死啊,全球狂炼大模型,一互联网的数据不够用,根本不够用。训练模型搞得跟《饥饿游戏》似的,全球AI研究者,都在苦恼怎么才能喂饱这群数据大胃王。尤其在多模态任务中,这一问题尤为突出。一筹莫展之际,来自人大系的初创团队,用自家的新模型,率先在国内把“模型生成数据自己喂自己”变成了现实。而且还是理解侧和生成侧双管齐下,两侧都能生成高质量、多模态的新数据,对模型本身进行数据反哺。模型是啥?中关村论坛上刚刚露面的多模态大模型Awaker1.0。团队是谁?智子引擎。由人大高瓴人工智能学院博士生高一钊创立,高

如何将Dnsmasq配置为DHCP中继服务器 如何将Dnsmasq配置为DHCP中继服务器 Mar 21, 2024 am 08:50 AM

DHCP中继的作用是将接收到的DHCP数据包转发到网络上的另一个DHCP服务器,即使这两个服务器位于不同的子网中。通过使用DHCP中继,您可以实现在网络中心部署一个集中式的DHCP服务器,并利用它为所有网络子网/VLAN动态分配IP地址。Dnsmasq是一种常用的DNS和DHCP协议服务器,可以配置为DHCP中继服务器,以帮助管理网络中的动态主机配置。在本文中,我们将向您展示如何将dnsmasq配置为DHCP中继服务器。内容主题:网络拓扑在DHCP中继上配置静态IP地址集中式DHCP服务器上的D

美国空军高调展示首个AI战斗机!部长亲自试驾全程未干预,10万行代码试飞21次 美国空军高调展示首个AI战斗机!部长亲自试驾全程未干预,10万行代码试飞21次 May 07, 2024 pm 05:00 PM

最近,军事圈被这个消息刷屏了:美军的战斗机,已经能由AI完成全自动空战了。是的,就在最近,美军的AI战斗机首次公开,揭开了神秘面纱。这架战斗机的全名是可变稳定性飞行模拟器测试飞机(VISTA),由美空军部长亲自搭乘,模拟了一对一的空战。5月2日,美国空军部长FrankKendall在Edwards空军基地驾驶X-62AVISTA升空注意,在一小时的飞行中,所有飞行动作都由AI自主完成!Kendall表示——在过去的几十年中,我们一直在思考自主空对空作战的无限潜力,但它始终显得遥不可及。然而如今,

阿里7B多模态文档理解大模型拿下新SOTA 阿里7B多模态文档理解大模型拿下新SOTA Apr 02, 2024 am 11:31 AM

多模态文档理解能力新SOTA!阿里mPLUG团队发布最新开源工作mPLUG-DocOwl1.5,针对高分辨率图片文字识别、通用文档结构理解、指令遵循、外部知识引入四大挑战,提出了一系列解决方案。话不多说,先来看效果。复杂结构的图表一键识别转换为Markdown格式:不同样式的图表都可以:更细节的文字识别和定位也能轻松搞定:还能对文档理解给出详细解释:要知道,“文档理解”目前是大语言模型实现落地的一个重要场景,市面上有很多辅助文档阅读的产品,有的主要通过OCR系统进行文字识别,配合LLM进行文字理

特斯拉机器人进厂打工,马斯克:手的自由度今年将达到22个! 特斯拉机器人进厂打工,马斯克:手的自由度今年将达到22个! May 06, 2024 pm 04:13 PM

特斯拉机器人Optimus最新视频出炉,已经可以在厂子里打工了。正常速度下,它分拣电池(特斯拉的4680电池)是这样的:官方还放出了20倍速下的样子——在小小的“工位”上,拣啊拣啊拣:这次放出的视频亮点之一在于Optimus在厂子里完成这项工作,是完全自主的,全程没有人为的干预。并且在Optimus的视角之下,它还可以把放歪了的电池重新捡起来放置,主打一个自动纠错:对于Optimus的手,英伟达科学家JimFan给出了高度的评价:Optimus的手是全球五指机器人里最灵巧的之一。它的手不仅有触觉

See all articles