根据PHP手册,session.gc_probability和session.gc_divisor声明gc将基于此概率发生。我知道了。
我不清楚的是这个概率是基于会话还是整体。
因此,如果GC的概率为1%(1/100),那是否意味着如果一个会话不断扩展,每次有1%的更改时,特定会话将被清除?或者这是否意味着所有现有会话(以及新会话)的1%将为所有其他现有会话触发GC?
我很确定这是后者,我只是想确定一下。
这个问题的目的是在我们的网站上,我希望用户有长期会议(6个月)。如果所有会话的1%触发GC,那么这有效地消除了长期会话的目的,因为GC最终会在每两个小时发生一次。
答案 0 :(得分:11)
每次执行PHP脚本并启动会话时,都有可能会扫描会话文件夹,从而终止旧会话。
清理只会删除在特定时间内未访问的会话。但是,PHP不保证会话将在该时间内被销毁。
您的长期会话策略应该可以正常运行,但您可能希望将1%减少到0.1%
需要注意的另一件事是操作系统可能会在重启期间清理/ tmp文件夹,即使PHP不会这样做。
答案 1 :(得分:7)
上次我查看源代码,每次调用session_start()“掷骰子”可以说,使用除数和概率。如果您点击,则会删除session.save_path
目录中早于session.gc_maxlifetime
的所有文件。我忘记了它是否使用了文件的修改或访问时间,虽然它在正常情况下无关紧要,因为php默认会在脚本执行结束时覆盖会话文件,因此mod和访问时间几乎总是非常紧密地匹配。 / p>
// Rough psuedo code of how php's session_start() function works regarding garbage collection.
function session_start() {
$percentChanceToGC = 100 * ini_get('session.gc_probability') / ini_get('session.session.gc_divisor');
$shouldDoGarbageCollection = rand(1, 100) < $percentChanceToGC;
if ($shouldDoGarbageCollection) {
$expiredCutoffTime = time() - ini_get('session.gc_maxlifetime');
foreach (scandir(ini_get('session.save_path')) as $sessionFile) {
if (filemtime($sessionFile) < $expiredCutoffTime) {
unlink($sessionFile);
}
}
}
// ... rest of code ....
}
我不知道如果你希望它们至少活6个月,你最终会有多少个会话文件。考虑到php可能需要一段时间来统计数千个文件来确定它们的年龄。也许考虑其他选项来持久存储这些数据。或者您可以禁用php gc并只运行一个cron作业来删除陈旧的会话文件。否则,1%的请求将触发gc并且必须等待php;换句话说,它可能会滞后。
答案 2 :(得分:2)
我不是这方面的专家,但是通过阅读手册,我会提请你注意另一个设置,session.gc_maxlifetime
。来自文档:
session.gc_maxlifetime
指定数据被视为“垃圾”并可能被清除的秒数。会话开始时可能会收集垃圾(取决于session.gc_probability
和session.gc_divisor
)。
因此,如果您将此设置设置为合适的值(60 * 60 * 24 * 365 / 2
半年,那么15768000
),那么无论其他什么,相应的数据都不符合垃圾回收的条件设置是。