限制会话id服务端不共享_多台服务器session共享,你用哪种方案

本文探讨了在多台服务器环境下实现PHP Session共享的需求,解析了PHP Session的工作原理,并详细介绍了通过设置session.cookie_domain、数据库存储、Memcache及Redis等方案来实现session共享。同时,对比了各种存储引擎的优缺点,如Redis在session机器重启时的优势以及在内存管理和性能上的考虑。
摘要由CSDN通过智能技术生成

为什么要session共享

现在稍微大一点的网站基本上都有好几个子域名,比如www.feiniu.com, search.feiniu.com, http://member.feiniu.com,这些网站如果需要共用用户登录信息,那么就需要做到session共享,当然前提是有相同的主域。

PHP的session原理

客户端访问php页面,执行session_start,生成session_id,一般我们是把session_id存储到cookie上,session内容保存在服务端,客户端访问访问不同的页面都会把session_id传到服务端,通过session_id来获取session内容。

流程是这样,可是不同的服务器会对同一个客户端产生不同的session_id,这样的话不同服务器就不能得到相同的session内容了。而且PHP 默认的 SESSION 数据都是分别保存在本服务器的文件系统中。

所以我们要解决session共享,就必须解决两个问题:

1. 多台服务器用同一个session_id

这个比较容易解决,只要在php中设置存session_id的cookie域名

为网站主域就可以了

打开PHP.ini, 设置session.cookie_domain = .feiniu.com,

当然也可以在php代码当中

设置ini_set("session.cookie_domain","feiniu.com");

2. 多台服务器用同一个session_id访问到相同的session内容

要实现这点,就必须把session内容存储到让所有服务器都能访问到的地方,

php的session内容是默认存储到本服务器的文件中的,

一般的解决方案是存入数据库,memcache或者redis这种缓存服务器,

当然用默认的文件存储方式也可以,用NFS统一存储。

3. 如何选择存储引擎

默认文件存储:这种方式的session销毁依托于php垃圾收集器,在高并发或销毁时间较长的情况下,在SESSION目录下产生大量文件,当然可以设置分级目录进行 SESSION 文件的保存。

这会导致两个问题:第一、查找文件慢;第二,每个目录下可容纳的文件数是有限的,可能会导致新SESSION储存失败。

1) 设置Session存储的引擎,php.ini 文件

[Session]

session.save_handler = files

session.save_path = /data/SessionLogs

2)默认情况下的Session的使用

/*** session的使用* 默认情况(不更改session.save_handle参数时),是存储在文件file中的* 默认情况下使用session的情况(用户24分钟内没有刷新操作会过期)* 每个用户对应唯一session_id,每一个session_id对应服务器中存储的一个session文件,这个文件中存储了当前session_id的信息,比如下面,就存储了name和age的键值*/

session_start();

echo session_id();

echo "
";

$_SESSION['age'] = 26;

$_SESSION['name'] = 'xiaobudiu';

var_dump($_SESSION);

3)在服务器中存储的形式是这样的

数据库存储:把Session存储在数据库里可以防止Session数据被垃圾收集器删除,可以固化存储session数据。但是用数据库来同步session,会加大数据库的IO,增加数据库的负担。而且数据库读写速度较慢,不利于session的适时同步。

memcache存储:

以这种方式来同步session,不会加大数据库的负担,并且安全性比较高,把session放到内存里面,比从文件中读取要快很多。

但是memcache把内存分成很多种规格的存储块,有块就有大小,这种方式也就决定了,memcache不能完全利用内存,会产生内存碎片,如果存储块不足,还会产生内存溢出

那些不需要“分布”的,不需要共享的,或者干脆规模小到只有一台服务器的应用,memcached不会带来任何好处,相反还会拖慢系统效率,因为网络连接同样需要资源。

Redis存储:

与memcache相比,redis访问稍稍慢一点点,好处是:redis支持的数据结构较多,可以存储数组或对象,而memcache只能存储字符串。

在session机器重启的情况下,memcache所有用户都必须重新获得 session,而redis不会在突然涌来大量用户产生了很多数据把存储 session 的机器内存占满了的情况下,memcache 会罢工,所有 key 都没过期的话就不停的覆盖最后写入的数据,而 redis 只是会变慢 ,不会影响程序的逻辑。

1)设置php.ini 文件中的session.save_handle 和session.save_path

session.save_handler = Redis

session.save_path = "tcp://localhost:6379"

注1:如果连接的是远程redis,需要将localhost换成对应的远程ip地址。像这样

session.save_handler = Redis

session.save_path = "tcp://47.94.203.119:6379"

注2:如果为redis已经添加了auth权限(requirpass),session.save_path项则应该这样写

session.save_handler = Redis

session.save_path = "tcp://47.94.203.119:6379?persistent=1&database=10&auth=myredisG506"

2)使用redis存储session信息

/*** 将session存储在redis中*/

session_start();

echo session_id();

echo "
";

$_SESSION['age'] = 26;

$_SESSION['name'] = 'xiaobudiu';

$_SESSION['sex'] = 'man';

var_dump($_SESSION);

在redis上是以这样的形式进行存储的

使用Redis存储Session,并设置Session会话存活时间以及Session中某一元素存活时间

封装session类 b.php

/*** session控制类**/

class Session

{

function __construct($lifetime = 3600)

{

//初始化设置session会话存活时间 ini_set('session.gc_maxlifetime',$lifetime);

}

/*** 设置当前会话session的key-value* @param String $name session name* @param Mixed $data session data* @param Int $expire 有效时间(秒)*/

function set($name, $data, $expire = 600)

{

$session_data = array();

$session_data['data'] = $data;

$session_data['expire'] = time()+$expire;

$_SESSION[$name] = $session_data;

}

/*** 读取当前会话session中的key-value* @param String $name session name* @return Mixed*/

function get($name)

{

if(isset($_SESSION[$name])) {

if($_SESSION[$name]['expire'] > time()) {

return $_SESSION[$name]['data'];

}else{

self::clear($name);

}

}

return false;

}

/*** 清除当前session会话中的某一key-value* @param String $name session name*/

function clear($name)

{

unset($_SESSION[$name]);

}

/*** 删除当前session_id对应的session文件(清空当前session会话存储)*/

function destroy()

{

session_destroy();

}

}

session类的使用:d.php

require_once 'b.php';

session_start();

$session = new Session();

$session->set('wan','kkkk',1966);

$session->set('name','xiaobudiu');

$session->set('age',26);

$session->set('sex','man');

//输出当前会话的session存储数据var_dump($_SESSION);

//unset掉某一个session属性//$session->clear('name');

//删除当前session_id对应session文件//$session->destroy();//echo $session->get('sex');

redis中显示:

以上内容希望帮助到大家,需要更多文章可以关注公众号:PHP从入门到精通,很多PHPer在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提升,对此我整理了一些PHP高级、架构视频资料和大厂PHP面试PDF免费获取,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值