爱玩科技网
您的当前位置:首页PHPSession可能会引起并发问题

PHPSession可能会引起并发问题

来源:爱玩科技网
PHPSession可能会引起并发问题

PHP Session可能会引起并发问题

在进⾏Web应⽤程序开发的时候,⼈们经常会⽤Session存储数据。但可能有⼈不知道,在PHP中,Session使⽤不当可能会引起并发问题。

如果同⼀个客户端并发发送多个请求,⽽每个请求都使⽤了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锁定问题就不会出现。

void session_write_close ( void )

End the current session and store session data.

Session data is usually stored after your script terminated without the need to call session_write_close(), but as session data is locked toprevent concurrent writes only one script may operate on a session at any time. When using framesets together with sessions you will

experience the frames loading one by one due to this locking. You can reduce the time needed to load all the frames by ending the sessionas soon as all changes to session variables are done. 案例:

session_start()后 对应的session⽂件是被锁定的,直到当前脚本结束才会解锁。

在锁定期间,令⼀个进程访问相同session id 要等⽂件解锁后session_start()才会开始。

解决办法是在 session 设置好数据后调⽤ session_write_close() 将数据写⼊⽂件并且结束session例如如下代码

PHP codesession_name(\"STEST\");session_id(\"TESTID\");session_start();

$_SESSION[\"count\"]=0;session_write_close();sleep(10);

echo \"success\";>

如果不加⼊session_write_close();

并发3个进程访问该页⾯,第⼀个进程执⾏10秒 第⼆个执⾏20秒 第三个执⾏30秒。加⼊session_write_close()后

并发3个进程会同时在10秒后执⾏完成

因篇幅问题不能全部显示,请点此查看更多更全内容