`
天梯梦
  • 浏览: 13733686 次
  • 性别: Icon_minigender_2
  • 来自: 洛杉矶
社区版块
存档分类
最新评论

PHP Session可能会引起并发问题

 
阅读更多

在进行Web应用程序开发的时候,人们经常会用Session存储数据。但可能有人不知道,在PHP中,Session使用不当可能会引起并发问题。印度医疗行业软件解决方案提供商Plus91 Technologies高级工程师Kishan Gor在个人博客上对这个问题进行了阐释。

 

如果同一个客户端并发发送多个请求,而每个请求都使用了Session,那么PHP Session锁的存在会导致服务器串行响应这些请求,而不是并行。这是因为在默认情况下,PHP使用文件存储Session数据。对于每一个新的 Session,PHP会创建一个文件,并持续向其中写入数据。所以,每次调用session_start()方法,就会打开Session文件,并取得 文件的独占锁。这样,如果服务器脚本正在处理一个请求,而客户端又发送了一个同样需要使用Session的请求,那么后一个请求会阻塞,直至前一个请求处 理完成释放了文件上的独占锁。不过,这只限于来自同一个客户端的多个请求,也就是说,来自一个客户端的请求并不会阻塞另一个客户端的请求。

如果脚本很短,这通常没有问题。但如果脚本运行时间比较长,那就可能会产生问题。在现代Web应用程序开发中,有一个非常常见的情况,就是使用 AJAX技术在同一个页面内发送多个请求获取数据。如果这些请求都需要使用Session,那么第一个请求到达服务器后会取得Session锁,其它请求 就必须等待,所有请求将串行处理,即使它们彼此之间并没有依赖关系。这将大大增加页面的响应时间。

 

有一个方法可以避免这个问题,就是在使用完Session以后立即调用session_write_close()方法关闭Session。这样 Session锁就会释放,即使当前脚本还在等在处理。需要注意的是,调用该方法后,当前脚本就不能进一步操作Session了。

需要特别指出的是,本文所陈述的问题和观点只适用于使用session_start()方法的PHP默认Session管理模式。比如,有用户就指出,如果将应用程序托管在AWS EC2上,并正确配置DynamoDB,Session锁定问题就不会出现。

 

实例讲解:

PHP默认的会话处理器是session.save_handler = files(即文件)。如果同一个客户端同时并发发送多个请求(如ajax在页面同时发送多个请求),且脚本执行时间较长,就会导致session文件阻塞,影响性能。因为对于每个请求,PHP执行session_start(),就会取得文件独占锁,只有在该请求处理结束后,才会释放独占锁。这样,同时多个请求就会引起阻塞。

 

session阻塞简单演示
创建2个php文件:session_a.php,session_b.php。

<?php
// session_a.php
session_start();
$_SESSION['a'] = date('H:i:s');
// session_write_close();

sleep(5);
echo $_SESSION['a'];

 

<?php
// session_b.php
session_start();
$_SESSION['b'] = date('H:i:s');
// session_write_close();

sleep(5);
echo $_SESSION['b'];

 

同时访问这2个脚本,你会发现,其中一个脚本比另一个延迟了5秒。而当我们将文件中的session_write_close()函数注释取消掉后,再来同时访问发现2个脚本可以同时执行了。

 

session锁定处理机制
顺便提一下,session_commit()是session_write_close()的别名,即也可以使用前者替代后者。

当session_start()调用时,session处理机制默认会打开或创建一个seesion文件,且会立即给这个文件上了一个锁定状态(locked)。当session_commit()调用时或脚本执行完成后该文件会被解锁(unlocked)。

锁定状态有个重要的影响:同时请求使用了session的PHP脚本,并非并列执行的,而是分离的。如果当用户发起了一个请求,同时发起另一个请求便会被阻塞,直至前一个请求完全完成。

 

Session锁定的好处
请不要勿以为这所谓的阻塞现象是PHP的BUG,当然不是,相反有些时候分离执行才是正确的做法。考虑一下购物车案例:

用户发起A请求,脚本读取用来显示购物车物品的session数据;
在A请求完成之前,用户便点击了“加入购物车”按钮,发送了个B请求;
B等待A请求完成,然后向session中新增数据;
如果没有对session进行锁定会发生什么?

B没有等待A完成,读取并写入session数据;
A请求完成并写入之前读取的session数据,覆盖了上述B写入的数据;
所以,我们在使用session时应当考虑当前实际环境。

 

ThinkPHP如何解决session阻塞
最近开始使用国内的PHP框架ThinkPHP,便遇见了阻塞问题,因为没仔细看官方文档,调试许久未果,差点一怒之下放弃该框架,后发现配置项里有个“SESSION_AUTO_START”配置,用于自动加载session,果断设置为FALSE,一切恢复正常。

 

在需要使用session的时候,可以使用PHP自带函数:

session_start();
//...
session_commit();   // 或session_write_close()
也可以用TP风格方式:

session('[start]');
//...
session('[pause]');

 

参考:

http://www.infoq.com/cn/news/2015/01/php-session-concurrency-problems

http://www.phpddt.com/php/php-session-problem.html

http://www.blhere.com/984.html

 

转自: PHP Session可能会引起并发问题

 

 

分享到:
评论

相关推荐

    PHP中Session可能会引起并发问题

    然而,如果不理解其工作原理,Session可能会引发并发问题,导致性能下降,特别是在高并发场景下。 PHP默认使用文件系统来存储Session数据。每个新的Session都会创建一个唯一的文件,如`sess_XXXXX`,其中`XXXXX`是...

    浅析PHP中Session可能会引起并发问题

    但可能有人不知道,在PHP中,Session使用不当可能会引起并发问题。印度医疗行业软件解决方案提供商Plus91 Technologies高级工程师Kishan Gor在个人博客上对这个问题进行了阐释。 如果同一个客户端并发发送多个请求,...

    php session的锁和并发

    PHP的Session机制在处理并发请求时,可能会遇到一系列问题,主要涉及到锁的使用以及数据的一致性。在本文中,我们将深入探讨这些问题,并尝试找出解决方案。 首先,让我们了解PHP如何处理Session数据。当PHP程序...

    PHP中Session引起的脚本阻塞问题解决办法

    然而,不当使用Session可能会引发脚本阻塞问题,导致并发请求处理效率降低。本文将深入探讨这个问题,并提供解决方案。 首先,让我们理解Session阻塞的根本原因。PHP的Session机制依赖于将Session数据存储在文件中...

    PHP session文件独占锁引起阻塞问题解决方法

    然而,这种机制在高并发环境下可能会引发阻塞问题,主要是由于文件独占锁的机制。 当一个PHP脚本调用`session_start()`时,它会获取当前会话文件的独占锁,确保同一时间内只有一个请求能访问该会话数据。如果同一...

    PHP 解决session死锁的方法

    然而,当PHP处理大量数据或并发请求时,可能会遇到Session死锁的问题。死锁发生时,一个请求正在写入Session数据,而其他请求在等待这个写入过程完成,导致它们无法继续执行,从而影响了应用程序的性能和用户体验。...

    PHP编程中的Session阻塞问题与解决方法分析

    然而,Session在某些情况下可能会引发阻塞问题,导致多个请求等待同一个Session文件的解锁,从而影响到网站的性能。本文将深入探讨PHP Session阻塞的原理、原因,并提出相应的解决方法。 ### Session阻塞原理 PHP...

    php session_start()出错原因分析及解决方法

    除了上述问题之外,还可能会遇到其他的会话错误,例如由于文件权限设置不当导致无法正常写入会话数据到session.save_path指定的目录;或者因为PHP会话锁机制导致并发访问时的冲突。这就需要检查PHP的配置选项,例如...

    IIS PHP环境Temp文件夹的权限问题引起的网站故障

    当PHP处理大量并发请求时,如果无法正常清理session文件,这些文件会堆积在Temp文件夹中,占用大量资源,从而导致系统响应变慢。 标签中的"Temp文件夹"和"权限"是问题的关键。Temp文件夹中的文件数量过多,且由于...

    中意广告联盟程序PHP源代码

    《中意广告联盟程序PHP源代码》是一款基于PHP语言开发的广告联盟系统,它为网站主和广告商提供了一个互动的平台,使他们能够有效地进行...但请始终谨记,任何未经授权的商业使用都可能带来版权问题,务必遵守法律法规。

Global site tag (gtag.js) - Google Analytics