什么可以导致PHP脚本在创建文本变量时简单地停止?

时间:2013-11-25 19:23:34

标签: php mysql

我遇到了我几个月来一直试图追踪的最奇怪的问题。我添加了在基于MySQL的日志中创建日志条目的调试代码行和行,结果没有意义。

基本上,脚本有时会停止。有时它会随机出现,然后在相同的位置进行十几次,然后它可能会一直持续,然后在下次再次进行。

更多详情:

每隔15分钟,我循环查看一个客户列表,每个客户端都有一个需要为电子邮件解析和收集的数据列表。如果此脚本的先前版本已在运行(即存在小于5分钟的日志条目),则不会再次执行该脚本。因此,如果我看到日志条目中断超过几分钟,然后在第一次启动后15分钟再开始,我就知道出了问题。日志中最奇怪的情况如下:

我在日志中输入我要为客户端X创建数据库查询。然后我创建一个包含客户端ID和星期几(date("l", strtotime("now")))的SQL代码的变量。然后我记录查询已成功创建。请注意,查询仅存在于PHP变量中,并且尚未提交给MySQL!

那么,让我举一个例子,说明我在日志中看到的内容:

  • 下午3:00:00 - (脚本开始)
  • 下午3:00:00 - (它通过客户端循环)
  • 3:00:04 pm - (已通过一些客户,现在正在客户端20上工作)
  • 3:00:04 pm - 为客户端20创建查询
  • (如果没有任何日志条目至少5分钟,则日志将在此处结束,直到脚本在15分钟后自动重新启动)
  • 下午3:15:00 - (脚本开始)
  • 下午3:15:00 - (它通过客户端循环)
  • 3:15:04 pm - (它已经通过一些客户,正在跳过客户端20,因为这显然有问题,现在正在客户端21上工作)
  • 3:15:04 pm - 为客户端21创建查询
  • 3:15:04 pm - 成功创建了客户端21的查询
  • (如果没有任何日志条目至少5分钟,则日志将在此处结束,直到脚本在15分钟后自动重新启动)
  • 下午3:30:00 - (脚本开始)
  • 3:30:00 pm - (它通过客户端循环)
  • 3:30:04 pm - (它已通过一些客户,现在正在客户端20上工作)
  • 3:30:04 pm - 为客户端20创建查询

然后冲洗并重复。现在持续几个小时,它将在它为客户端20创建查询之前失败并在它为客户端21创建查询之后失败。然后,突然之间,它可能会一直通过其他客户端。然后脚本再次启动并继续相同的怪异循环。每隔一天左右,这将发生在一两个其他客户身上。

查询很简单,如下所示:

$sql = "
select fldClientName
from client
where fldClientId = $clientId
and fldEmail".date("l", strtotime("now"))." = 1
";

基本上,如果今天是星期一,它应检查fldEmailMonday是否设置为1,让我们知道此客户端今天需要通过电子邮件发送。

这适用于我们的大量客户,但它只是随机地卡在一天或两天变化的一两个客户端上。再次,这是在$sql提交给MySQL之前发生的!我们陷入了变量$sql的创建。

当然,实际的查询要比我在这里写的要复杂得多,但$clientIddate("l", strtotime("now"))是静态文本中唯一的可变部分。

此外,我们多年来一直有同样的问题(我现在才开始更多地跟踪它),到现在为止,我们经历了三个PHP服务器和两个MySQL服务器 - 我们&# 39;我仍然遇到同样的问题,所以我们要确定它不是硬件问题(如内存或硬盘)。

我不知道这可能是问题所在,但是这个脚本是由一个在lynx中启动它的cron作业运行的。这是在我接受代码之前建立的,我不知道它的原因。每当我们手动运行它时(我通常使用php index.php代替lynx hostname://index.php),它似乎永远不会失败。

这可能是Lynx的一个问题吗?如果是这样,为什么它在70%的时间内都有效,否则会失败?为什么是随机性?

或者我应该弄清楚是否存在PHP问题?我们正在运行5.3.2版本(是的,有点旧,但除非绝对必要,否则我们的服务器管理员不想搞砸它。)

我猜测Lynx已被使用,所以我们得到了Apache日志(顺便提一下,除了一些已弃用的代码警告,我现在也试图摆脱它),我猜这个如果我运行php index.php,我就不会获得apache日志。也许我还缺少了另一个可能对此有帮助的日志文件?

此外,它不能成为导致它的日志记录代码本身,因为它只提交纯静态文本和在创建SQL代码之前建立的客户端ID。

脚本在更多位置失败,但这对我来说真的没用。

关于什么可能导致这样的事情的任何想法?

还有什么想法我可以做些什么来追踪它?我的意思是,我在创建一个变量之前和之后都记录了它,并且它介于两者之间 - 现在确定我可以在这里记录多少...

3 个答案:

答案 0 :(得分:2)

可能是你的问题与PHP,MySQL或Apache无关,可能更多的服务器环境案例,一些操作系统冻僵僵尸案例。 你是否在Lynx以外的任何其他环境中尝试过cronjobs?我的意思是在本地或其他服务器上。

您是否检查过服务器日志以查找任何警报/错误消息?

答案 1 :(得分:1)

我调试它的第一步是从$ sql生成中提取day变量。我看不出它有什么问题,所以我怀疑它会取得多大成就,但至少它会以某种方式确认是否会导致问题。

$day = date("l", strtotime("now"));
$sql = "
select fldClientName
from client
where fldClientId = $clientId
and fldEmail{$day} = 1
";

您甚至可以检查$day的值,如果无效则抛出RuntimeException。但正如我所提到的,我怀疑答案在其他地方。

答案 2 :(得分:1)

总结一下对话,我的主要策略是简化cron调用中涉及的软件组件的数量。所以,这意味着改变:

Cron -> Lynx -> Apache -> Script

Cron -> Script

如果新方法仍然存在问题,那么至少有两个组件被排除(也可能更快)。从你的评论来看,这听起来像是修正了它;如果是这样,很好。

我在此重申的一个更广泛的观点是,虽然一个具有挑战性的问题值得研究,但有一点需要出于成本原因最好以另一种方式解决问题。这可能就是这样一个场合,Lynx失败的奥秘可能只能坚持下去!