解决PHP 服务器以文件储存 SESSION 的两个问题

jopen 11年前

在默认情况下,我们在服务器上的SESSION是以文件储存的,这种情况至少到带来两个问题:

  1. 在高并发或销毁时间较长的情况下,在SESSION目录下产生大量文件。这会导致两个问题:第一、查找文件慢;第二,每个目录下可容纳的文件数是有限的,可能会导致新SESSION储存失败。
  2. 在SESSION初始化时,会锁住文件,直到程序执行完毕才释放,导致其它并发的脚本在初始化SESSION时产生阻塞。这意味着其它的脚本都在等待这个锁,从而产生性能问题。

这两个问题随便发生一个,都是不可接受的,如果产生了叠加效果,则更恐怖。

以下两个脚本是证实问题2的依据:

<?php  // a.php  session_start();  $_SESSION['MYNAME'] = 'HEIING';  sleep(10); // 睡10秒,以便观察,通常这里是一些数据库及业务逻辑操作  echo 'done';
<?php  // b.php  session_start();  echo $_SESSION['MYNAME'];  echo "\ndone";
先运行a.php,再运行b.php,会发现阻塞。

解决方案:

  1. 写入SESSION后,尽早使用 session_write_close() 进行解锁,比如在a.php的sleep之前添加一行session_write_close();
  2. 使用内存等无锁方案,比如储存到MemCached、MySql中
  3. 使用Cookie保存到客户端,用户信息可以加密后写到Cookie中,比如使用TEA等轻量级的加密方案。