我们的PHP项目有一个维护脚本,它以特定的时间间隔运行,并根据各个计划执行一系列任务,将其视为php的CRON
。
我遇到的问题是,在某些时间间隔内出现的某些任务的运行时间超过了我们的强化会话长度(30分钟),因此会话在该任务的过程中到期,结束了过早。
仅供参考:我不是在谈论脚本运行时限制,我们已经使用set_time_limit()
来允许长时间运行的进程。
问题:有没有办法在执行脚本期间以一种重置会话到期时间的方式“触摸”会话?即设置会话变量是否合适,或者是否需要特定的PHP函数才能完成此任务?
更具体地说,我们每分钟都有一个实际的CRON
作业:
* * * * * user curl -XGET https://domain.com/maintenance.php
...反过来使用我们的内部系统来查找当时计划运行的任务,其中一些任务简短而有些,而且有些任务既繁琐又复杂。正是在长期复杂(> 30分钟运行时)的过程中发生了上述问题。
编辑:总结下面的许多评论......
我们希望避免发布额外的RPC来实现这一目标,我正在寻找的是像假想touch_session()
这样的解决方案。
我相信我们可以排除更改会话值作为选项,因为在请求关闭之前,更改不会记录在会话中,在我们的情况下为时已晚。
我们正在使用数据库进行会话管理,因此我们可以简单地编写自己的touch_session()
方法,该方法可以被调用,只需使用SQL查询来更新时间戳la {{ 1}}。 这有什么陷阱吗?
如果不是以上任何一项,是否有其他选项不需要进一步的rpc?
答案 0 :(得分:1)
如评论中所述,您可以使用curl访问另一个触及会话的脚本
<强> touch.php 强>
<?php
session_name('theNameOfYourSessionId');
session_start();
在你的维护脚本中用这样的curl来调用它:
$sid = session_id();
exec('user curl -XGET https://domain.com/maintenance.php?theNameOfYourSessionId='.$sid)
这应该可以解决问题。
您只需使用file_get_contents代替卷曲,以避免卷曲问题。
$sid = session_id();
file_get_contents('https://domain.com/maintenance.php?theNameOfYourSessionId='.$sid);
另一种方法是简单地接受会话可能已经死亡并从数据库中恢复它们。正如您所提到的,您使用多个应用服务器,无论如何都需要一个多应用服务器解决方案,
那么为什么不使用提供的会话ID作为数据库中的标识符并将会话内容存储在那里?输入脚本并且所需会话为空时,请调用数据库并将其还原。
答案 1 :(得分:1)
尽管有几个解决方案正在浮出水面,但没有一个满足我们的要求,它们要么比它们的价值更高,有安全问题,要么需要在大量应用程序中实施大量工作。
在PHP的情况下,$ _SESSION只是存储在会话记录中的数据的副本,直到请求结束并且新数据覆盖旧数据,因此对$ _SESSION的任何操作都不会影响实际的会话记录到期时间。系统
因为在我们独特的情况下,我们使用MySQL进行会话管理,最简单的答案是使用简单查询创建我们自己的touch_session()
方法:
UPDATE sessions SET expiration = NOW() WHERE Session_ID = 'ABC123'
注意,我们的垃圾收集使用NOW() - 30分钟到期记录,因此在上面的查询中将到期时间设置为NOW()。
现在可以将这种快速方法添加到任何潜在的长时间运行的维护脚本中,在这些脚本中,它将经常被调用以避免会话到期,但通常不足以增加任何明显的开销。
希望这可以帮助处于类似情况的其他人。