清理 php 会话文件

Posted

技术标签:

【中文标题】清理 php 会话文件【英文标题】:cleanup php session files 【发布时间】:2010-10-13 20:23:09 【问题描述】:

在我的网站上,我使用 php 会话。会话信息存储在我的 ./session 路径中的文件中。几个月后,我发现这些会话文件永远不会被删除,现在这个目录中有 145.000 个。

这些应该如何清理?我是否必须以编程方式执行此操作,或者是否可以在某个地方使用可以自动进行此清理的设置?

编辑忘了说:这个网站在一个提供商处运行,所以我无法访问命令行。我确实有 ftp 访问权限,但会话文件属于另一个用户(我猜是网络服务器进程运行的那个)从我得到的第一个答案中,我认为这不仅仅是服务器或 PHP 上的设置,所以我想我会必须在 PHP 中为它实现一些东西,并定期从浏览器中调用它(可能来自在我家自己的机器上运行的 cron 作业)

【问题讨论】:

【参考方案1】:

要正确处理会话,请查看http://php.net/manual/en/session.configuration.php。

你会发现这些变量:

session.gc_probability session.gc_divisor session.gc_maxlifetime

这些控制每个页面请求运行的垃圾收集器 (GC) 概率。

您可以在脚本或 .htaccess 文件的开头设置ini_set(),这样您就可以在一定程度上确定它们有时会被删除。

【讨论】:

注意:如果您使用子目录选项来存储会话文件(请参阅上面的 session.save_path),那么垃圾收集不会自动发生。您将需要通过 shell 脚本、cron 条目或其他方法进行自己的垃圾收集。例如,以下脚本相当于将 session.gc_maxlifetime 设置为 1440(1440 秒 = 24 分钟): cd /path/to/sessions;找到-cmin +24 | xargs rm @Jehy 看起来 PHP 现在可以执行垃圾收集,即使您有自定义 session.save_path。 @DarrellBrogdon 您是否有关于使用自定义 session.save 路径时 PHP 的自动垃圾收集的资源或更多信息?如果是这样就好了。 @maartenmachiels PHP 文档和 php.ini 文件实际上提供了很多信息。但是,您必须仔细观察,并真正理解 GC 执行的计算以确定何时收集以及收集什么。【参考方案2】:

Debian/Ubuntu 使用 /etc/cron.d/php5 中定义的 cronjob 处理此问题

# /etc/cron.d/php5: crontab fragment for php5
#  This purges session files older than X, where X is defined in seconds
#  as the largest value of session.gc_maxlifetime from all your php.ini
#  files, or 24 minutes if not defined.  See /usr/lib/php5/maxlifetime

# Look for and purge old sessions every 30 minutes
09,39 *     * * *     root   [ -d /var/lib/php5 ] && find /var/lib/php5/ -type f -cmin +$(/usr/lib/php5/maxlifetime) -print0 | xargs -r -0 rm

maxlifetime 脚本通过检查 php.ini 简单地返回会话应保持活动状态的分钟数,如下所示

#!/bin/sh -e

max=1440

for ini in /etc/php5/*/php.ini; do
        cur=$(sed -n -e 's/^[[:space:]]*session.gc_maxlifetime[[:space:]]*=[[:space:]]*\([0-9]\+\).*$/\1/p' $ini 2>/dev/null || true);
        [ -z "$cur" ] && cur=0
        [ "$cur" -gt "$max" ] && max=$cur
done

echo $(($max/60))

exit 0

【讨论】:

感谢您的回答 Paul,正如我在我的问题的最新版本中所说,它不是从命令行运行它的选项,我会看看我是否可以说服我的提供者放置一些东西像这样在 cron 中。 多亏了这个,我发现一定有人把它剪切粘贴到无效。命令中的 & 现在是 &。服务器已经超过 2 年没有收集垃圾了。难怪这里闻起来这么难闻! 所以这完全绕过了通过 ini_set 设置的任何内容?难怪在脚本中设置 gc 什么都不做。 cron 条目只清理 /var/lib/php5 中的会话文件。 OP 询问是否清理他的自定义会话目录中的会话文件。因此,您需要创建一个遍历所有自定义目录的脚本,并且与@paul-dixon 在此处为 cron 条目编写的内容相同。 我很好奇为什么 Debian/Ubuntu 会这样做?在我们的例子中,我们有一个自定义 session.save_path,所以 cron.d 脚本没有看到任何会话文件。我们建立了太多陈旧的会话文件,以至于我们用完了 inode!值得庆幸的是,将 session.gc_probability 设置回 1(Ubuntu 默认设置为 0)解决了这个问题。【参考方案3】:

如果有人想使用 cronjob 执行此操作,请记住:

find .session/ -atime +7  -exec rm  \;

当有很多文件时真的很慢。

考虑改用这个:

find .session/ -atime +7 | xargs -r rm

如果文件名中有空格,请使用:

find .session/ -atime +7 -print0 | xargs -0 -r rm

xargs 将用要删除的文件填充命令行,然后运行 ​​rm 命令比 -exec rm \; 少很多,后者将为每个文件调用 rm 命令。

只要我的两分钱

【讨论】:

另外请记住,您可以使用-exec $cmd +; 而不是-exec $cmd \; 它将执行在一个命令中找到的所有文件,而不是为找到的每个文件运行一次命令。这与Andi 推荐的 xargs 非常相似。在此处阅读更多信息:unix.stackexchange.com/questions/195939/… 在我的情况下,在 docker 容器中(没有 CRON 初始值),找到... | xargs 太慢了,我应该运行find .session/sess_[a-d] -atime +7 | xargs -r rm 等等……【参考方案4】:

cd 到会话目录,然后:

1) 查看超过 40 分钟的会话: find . -amin +40 -exec stat -c "%n %y" \;

2) 删除超过 40 分钟的会话: find . -amin +40 -exec rm \;

【讨论】:

谢谢,这很有帮助。我将“第 2 步”与 Andi 的代码结合起来制作,这对我来说更快(我是 100%):find . -amin +40 | xargs -r rm【参考方案5】:

使用 cron 和 find 来删除早于给定阈值的文件。 例如删除至少一周未访问的文件。

find .session/ -atime +7  -exec rm  \;

【讨论】:

感谢您的回答,正如我在我的问题的最新版本中所说,它不是从命令行运行它的选项,我会看看我是否可以说服我的提供者放置类似的东西这在 cron 中。【参考方案6】:

你可以创建脚本 /etc/cron.hourly/php 并放在那里:

#!/bin/bash

max=24
tmpdir=/tmp

nice find $tmpdir -type f -name 'sess_*' -mmin +$max -delete

然后使脚本可执行(chmod +x)。

现在每小时将删除所有修改数据超过 24 分钟的会话文件。

【讨论】:

【参考方案7】:
# Every 30 minutes, not on the hour<br>
# Grabs maxlifetime directly from \`php -i\`<br>
# doesn't care if /var/lib/php5 exists, errs go to /dev/null<br>

09,39 * * * *   find /var/lib/php5/ -type f -cmin +$(echo "\`php -i|grep -i session.gc_maxlifetime|cut -d' ' -f3\` / 60" | bc) -exec rm -f  \\; >/dev/null 2>&1

细分: 仅文件:find /var/lib/php5/ -type f 早于分钟:-cmin 获取php设置:$(echo "`php -i|grep -i session.gc_maxlifetime 算一下:|cut -d' ' -f3` / 60" | bc) RM 匹配文件:-exec rm -f \;

【讨论】:

【参考方案8】:

我最好的猜测是您在共享服务器上,并且会话文件与所有用户混合在一起,因此您不能也不应该删除它们。如果您担心扩展和/或您的用户会话隐私,您可以做的就是将会话移至数据库。

开始将该 Cookie 写入数据库,到时候在多个服务器上扩展您的应用程序还有很长的路要走。

除此之外,我不会担心 145.000 个文件。

【讨论】:

感谢 Frankie,将其移至数据库的好主意,请记住这一点。【参考方案9】:

在cron下面使用:

39 20     * * *     root   [ -x /usr/lib/php5/maxlifetime ] && [ -d /var/lib/php5 ] && find /var/lib/php5/ -depth -mindepth 1 -maxdepth 1 -type f -cmin +$(/usr/lib/php5/maxlifetime) -print0 | xargs -r -0 rm

【讨论】:

以上是关于清理 php 会话文件的主要内容,如果未能解决你的问题,请参考以下文章

php PHP清理缓存文件夹

ORACLE定期清理INACTIVE会话

ORACLE定期清理INACTIVE会话

清理旧的googleappengine会话

/var/lib/php5 填充了空会话文件

我怎样才能给 Selenium Grid 中的会话无限的空闲时间,但清理断开连接的会话?