session阻塞机制解决方案

袁志蒙 2539次浏览

摘要:当开启session_start以后,这个session会一直开启,并且被一个用户使用。其他用户开启session的话要等待第一个session用户关闭以后才可以开启session,这样就造成了session阻塞...

当开启session_start以后,这个session会一直开启,并且被一个用户使用。其他用户开启session的话要等待第一个session用户关闭以后才可以开启session,这样就造成了session阻塞。

结合了PHP的Session机制,找到了阻塞的原因。由于PHP的Session信息是写入文件的,1个客户端占有1个session文件。因此,当 session_start被调用的时候,该文件是被锁住的,而且是以读写模式锁住的(因为程序中可能要修改session的值),这样,第2次调用 session_start的时候就被阻塞了。

解决session阻塞,使用session_write_close函数或session_commit函数(session_write_close的别名),作用是Write session data and end session,也就是写session的数据,同时关闭这个session。因此,我们可以在用完session之后,调用这个函数关闭session 文件即可解除锁定。一般,session是用来记录用户身份信息的,以便PHP进行身份认证,因此完全可以将session的读写放在页面刚开始执行的时候,在执行完以后,马上调用session_write_close函数即可。

举个例子,一目了然:

如果用户登录后需要处理某些数据时,执行的时间比较长(如5-6秒时),这时页面执行一个ajax去获取当前执行的进度时,就会出现在一直等待的问题,也就是session阻塞。

a.php

session_start();

$_SESSION['username'] = 'yzmcms';
$_SESSION['time'] = time();


// 解决session阻塞
session_write_close();

// 执行大量业务逻辑代码,时间大约5秒钟
sleep(5);

var_dump($_SESSION);

b.php

session_start();

var_dump($_SESSION);

如果a.php不加session_write_close函数的话,访问b.php的时候将是等待中,直到a.php执行完成后,b.php才会返回结果。

补充:

session默认是文件存储,也可以存在数据库或内存,存入内存可以使用Memcached和Redis技术,如果存入数据库或内存,则这些数据就是共享的可以同时读取。如以上代码。Redis读取时候,是共享的,不会出现等待。但是,我们会发现,Redis连接数,还是会保持着。并且连接数会增加,如果这个时候,你设置的Redis连接数过小,你会发现,很快Redis就挂掉了,所以还是建议使用以上函数来做处理。

随机内容

表情

共2条评论
  • 网友评论:

    大佬就是大佬

    2021-07-08 20:10:55 回复

    点击加载
  • 网友评论:

    2021-05-21 19:29:23 回复

    点击加载