简体   繁体   English

PHP的睡眠和MySQL不相处

[英]PHP Sleep and mysql not getting along

I have a program that works in run-once mode, but fails when I run it in background with a do-while-true loop that includes a sleep(60) delay. 我有一个可以运行一次的程序,但是当我在后台运行它时却执行失败,而该程序带有包含sleep(60)延迟的do-while-true循环。

if ($debug || $run_once) {check_mail($domain_mail_box, $mailboxes); exit;} 
    else {
        do {
            check_mail($domain_mail_box, $mailboxes);

#       sleep 60;
#       exec('sleep 60'); # wait a minute after completing each run
            $i=0; do { $i++; } while ($i < 3000000001);
        } while (TRUE);
    }
    exit(0);

Actually, all three of these attempts to get it to work properly fail. 实际上,这三种使它正常工作的尝试都失败了。 It's odd because I have it running beautifully on another server/system. 奇怪是因为我让它在另一个服务器/系统上完美运行。 (Both are dedicated CentOS boxes.) (两个都是专用的CentOS盒子。)

The failure is a MySQL failure. 失败是MySQL失败。 As part of the script, it writes to a log. 作为脚本的一部分,它写入日志。 The run-once and first runs with the delay write something like this for mysql_stat($Link): 0: Uptime: 605079 / 1: Threads: 2 / 2: Questions: 17458285 / 3: Slow queries: 0 / 4: Opens: 1287520 / 5: Flush tables: 1 / 6: Open tables: 1024 / 7: Queries per second avg: 28.852 / 一次运行并首先运行,并为延迟运行,为mysql_stat($ Link)这样写:0:正常运行时间:605079/1:线程:2/2:问题:17458285/3:慢查询:0/4:打开: 1287520/5:刷新表:1/6:打开表:1024/7:每秒平均查询次数:28.852 /

but once I insert the delay, I get the dreaded: 0: MySQL server has gone away / from mysql_stat. 但是一旦插入延迟,我就会感到恐惧:0:MySQL服务器已经离开了mysql_stat。

Any ideas what's going on? 有什么想法吗?

Hmmm. I think I've found some information that sheds light on my problem: this comment from http://php.net/manual/en/mysqli.close.php . 我想我发现了一些可以说明我的问题的信息: http : //php.net/manual/en/mysqli.close.php的注释。 I'm considering the problem explained, if not solved. 我正在考虑解释的问题,如果不能解决。 I'm actually solving by just creating and destroying the db link each time the program runs. 我实际上是通过在每次程序运行时创建和销毁db链接来解决的。 Simple enough and no great overhead, I hope. 我希望这很简单,没有太大的开销。

At least with PHP5.3.2 and Windows connecting by tcp, this differs by the old mysql_close() function in that it does not actually close out the tcp socket being used. 至少在PHP5.3.2和Windows通过tcp连接的情况下,这与旧的mysql_close()函数的不同之处在于,它实际上并未关闭正在使用的tcp套接字。 You should always use mysqli_kill() function before mysqli_close() to actually close and free up the tcp socket being used by PHP. 在mysqli_close()之前,您应该始终使用mysqli_kill()函数来实际关闭和释放PHP使用的tcp套接字。 Garbage collection after script execution nor mysqli_close() do not kill the tcp socket on their own. 脚本执行后的垃圾收集或mysqli_close()都不会自行杀死tcp套接字。 The socket would otherwise remain in 'wait' state for approximately 30 seconds, and any additional page loads/connection attempts would only add to the total number of open tcp connections. 否则,套接字将保持在“等待”状态约30秒,并且任何其他页面加载/连接尝试只会增加打开的tcp连接的总数。 This wait time does not appear to be configurable via PHP settings. 此等待时间似乎无法通过PHP设置进行配置。

In your comment you said, that you want to use timer in order to control data sync between function executions. 在您的评论中,您说过,您想使用计时器来控制函数执行之间的数据同步。

Cron jobs are much more reliable approach. Cron工作是更可靠的方法。 Thing, that you are trying to implement is an ugly solution. 您要实施的东西是一个丑陋的解决方案。

Trick that you should use in your case: 在您的情况下应该使用的技巧:

1) Make a cron that runs every minute, and do mail logic. 1)创建一个每分钟运行一次的cron,并执行邮件逻辑。

2) Add table 'cron_locks' to database with name column. 2)将表“ cron_locks”添加到具有名称列的数据库。 When your cron starts, you check if a there is a row in that table by name. 当您的cron启动时,您会按名称检查该表中是否有一行。

3) If lock is set, you should skip cron. 3)如果设置了锁定,则应跳过cron。 If lock is not set - you set it. 如果未设置锁定-则进行设置。

4) In the end of function you remove lock from db. 4)在函数末尾,您从db中删除了锁。

Please ask me for further explanation, if I was not clear enough. 如果我不够清楚,请询问我进一步的解释。 I believe that this is correct solution for your problem. 我相信这是解决您问题的正确方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM