php中session引起的脚本阻塞问题解决办法

时间:2018-06-30 作者:佚名 编辑:xiaoxin 来源:不甘平庸网

这个问题很多做php开发朋友应该都有遇到过,一个启用了session_start 页面,由于执行时间过长。导致通一个用户访问,另外一个很简单的启用session_start页面一直阻塞着。 直到第一个页面执行完了。第二个页面才可以读取。这个就是,我们常说的session阻塞机制。

解决session阻塞问题的办法:在session操作完成后调用session_write_close()即可避免此问题;

案例一:

使用session过程中,在开启session后,同一浏览器,执行同一程序,不同页面会被锁。不同浏览器不会出现这种情况。

疑问:是不是session_start导致了阻塞?

于是,我写了几个页面测试了一下,发现是session导致了阻塞,而其他两种情况不会造成阻塞。

查了下PHP的Bug列表,发现有人提出了这个问题:

Description:

------------

Calling session_start() appears to wait until other scripts have exited

that are using the same session. My guess is the 1st request locks the

session file for exclusive use, and the second request blocks until it

can open it.

PHP官方的回复是:

Thank you for taking the time to write to us, but this is not a bug.This is expected, the session file is locked to avoid corruption.

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

最简解决方法:

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

案例二:

上回说要改opencart其实是给opencart加一个抓取淘宝上的产品的功能,但是弄完后发现一个问题,就是当脚本在抓取的时候,因为这个过程比较慢,这个时候其他所有脚本的执行都被阻塞了,直到抓取完其他脚本才能依次执行。研究了半天没有结果,在知乎上问了下可能是session的问题,需要调用session_write_close()来解决,那么这个session_write_close()是干嘛用的呢,手册上这样写的:

结束当前session,保存session数据。

session数据通常会在脚本执行结束后被保存而并不需要调用session_write_close(),但是为保护session在任何时候都只能被一个脚本执行写操作,session的数据会被锁住。当同时使用框架网页和session时你会发现,框架里的网页会因为这个个锁定而逐个载入。你可以通过在所有的session数据修改保存结束后马上结束session来加快载入时间。

这就很好的解释了为什么我的抓取脚本会阻塞其他页面的原因。所以,如果你有一个需要执行时间比较长并用到session的ajax请求的话,就需要在服务器端调用session_write_close(),不然你的其他页面就都会被挂起直到请求结束!!!

相关阅读
PHP心得推荐
  • php实现的网页正文智能提取算法代码实例类
    php实现的网页正文智能提取算法代码实例类
    php实现的提取网页正文部分:最近研究百度结果页的资讯采集,其中关键环节就是从采集回的页面中提取出文章。因为难点在于如何去识别并保留网页中的文章部分,而且删除其它... [详情]
  • linux定时计划任务crontab命令详解
    crontab命令被用来提交和管理用户的需要周期性执行的任务,与windows下的计划任务类似,当安装完成操作系统后,默认会安装此服务工具,并且会自动启动crond进程,crond进程每分钟会定期检查是否有要执行的任务,如果... [详情]
  • PHP解决如抢购并发问题的几种实现方法
    PHP解决如抢购并发问题的几种实现方法
    对于商品抢购等并发场景下,可能会出现超卖的现象,这时就需要解决并发所带来的这些问题了在PHP语言中并没有原生的提供并发的解决方案,因此就需要借助其他方式来实现并发... [详情]
  • php用Imagick模块完美实现GIF动画缩略图代码实例
    php用Imagick模块完美实现GIF动画缩略图代码实例
    缩略图是个很常用的功能。它的实现并不复杂,但如果原图是GIF动画的话,问题就会变得繁琐一点。下面看看如何用PHP中的Imagick模块来完美实现GIF动画缩略图……... [详情]
  • php cli模式传递和获取参数的方法
    php cli模式传递和获取参数的方法
    在命令行里输入程序参数来更改其运行方式是很常见的做法。你也可以对CLI程序这样做。PHP CLI带有两个特殊的变量,专门用来达到这个。目的:一个是$argv变量,它通过命令行... [详情]
  • PHP开发常用数组函数
    PHP开发常用数组函数,记录下方便查看: [详情]
  • 用PHP正则表达式清除字符串的空白
    我们经常会处理来自用户输入或从数据库中读取的数据,可能在你的字符串中有多余的空白或制表符,回车等。存储这些额外的字符是有点浪费空间的。... [详情]
  • php include加载或查找文件的先后顺序
    include第一次找到某文件后,会缓存结果。下一次include相同的路径时,只取缓存结果而不会多重查找,这就导致了我们移除某文件后可能短暂的时间内include会报错(因为include机制发现缓存结果的路径不存在,不会往下... [详情]
频道推荐
本周推荐
点击排行