我遇到了我几个月来一直试图追踪的最奇怪的问题。我添加了在基于MySQL的日志中创建日志条目的调试代码行和行,结果没有意义。
基本上,脚本有时会停止。有时它会随机出现,然后在相同的位置进行十几次,然后它可能会一直持续,然后在下次再次进行。
更多详情:
每隔15分钟,我循环查看一个客户列表,每个客户端都有一个需要为电子邮件解析和收集的数据列表。如果此脚本的先前版本已在运行(即存在小于5分钟的日志条目),则不会再次执行该脚本。因此,如果我看到日志条目中断超过几分钟,然后在第一次启动后15分钟再开始,我就知道出了问题。日志中最奇怪的情况如下:
我在日志中输入我要为客户端X创建数据库查询。然后我创建一个包含客户端ID和星期几(date("l", strtotime("now"))
)的SQL代码的变量。然后我记录查询已成功创建。请注意,查询仅存在于PHP变量中,并且尚未提交给MySQL!
那么,让我举一个例子,说明我在日志中看到的内容:
然后冲洗并重复。现在持续几个小时,它将在它为客户端20创建查询之前失败并在它为客户端21创建查询之后失败。然后,突然之间,它可能会一直通过其他客户端。然后脚本再次启动并继续相同的怪异循环。每隔一天左右,这将发生在一两个其他客户身上。
查询很简单,如下所示:
$sql = "
select fldClientName
from client
where fldClientId = $clientId
and fldEmail".date("l", strtotime("now"))." = 1
";
基本上,如果今天是星期一,它应检查fldEmailMonday是否设置为1,让我们知道此客户端今天需要通过电子邮件发送。
这适用于我们的大量客户,但它只是随机地卡在一天或两天变化的一两个客户端上。再次,这是在$sql
提交给MySQL之前发生的!我们陷入了变量$sql
的创建。
当然,实际的查询要比我在这里写的要复杂得多,但$clientId
和date("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。
脚本在更多位置失败,但这对我来说真的没用。
关于什么可能导致这样的事情的任何想法?
还有什么想法我可以做些什么来追踪它?我的意思是,我在创建一个变量之前和之后都记录了它,并且它介于两者之间 - 现在确定我可以在这里记录多少...
答案 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失败的奥秘可能只能坚持下去!