首先,我远不是 Linux 专家,所以这可能是这里的问题,但无论如何,问题是:
我按照这里写的:http: //symcbean.blogspot.com/2010/02/php-and-long-running-processes.html
启动一个长时间运行的 PHP 进程。这在我的 Mac 上的 MAMP 配置中完美运行。然而,一旦我将它部署到我们的 VPS,我得到了一些非常奇怪的结果。
所以首先我做一个简单的测试,使用 SSH 连接:
echo '/usr/local/php53/bin/php -d memory_limit=512M -q /home/user/www/Update/Update.php;' | at now + 2minutes
结果:
warning: commands will be executed using /bin/sh
job 2300 at 2012-04-29 19:24
事实上,2 分钟后 php 脚本被执行。到目前为止,一切都很好。
接下来我尝试以下方法:
在我的浏览器中我打开:
www.myserver.com/Update/LaunchUpdates.php
此 php 脚本包含以下行:
exec("echo '/usr/local/php53/bin/php -d memory_limit=512M -q /home/user/www/Update/Update.php;' | at now + 2minutes");
发生的情况如下:我在 -l 处检查状态,我看到:
job 2304 at 2012-04-29 19:32
然后我等待 2 分钟并再次在 -l 处运行。我希望看到一个空的结果,但我得到:
job 2305 at 2012-04-29 19:34
2分钟后我得到
job 2306 at 2012-04-29 19:36
我对那里发生的事情一无所知。未执行 php 脚本,并且该作业似乎在 2 分钟后自行重新安排。这种情况一直持续到我完成工作为止。
有谁知道可能会发生什么?
更多信息:
cat /etc/*-release
Gentoo Base System version 1.6.14
更多细节。以下是 at 作业被调度时的内容:(at -c [ID])
#!/bin/sh
# atrun uid=1002 gid=100
# mail user 1
umask 33
SERVER_SIGNATURE=\<address\>Apache/2.2.20\ \(Unix\)\ mod_ssl/2.2.20\ OpenSSL/0.9.8o\ Server\ at\ xxx.yyyyy.com\ Port\ 80\</address\>"
"; export SERVER_SIGNATURE
HTTP_USER_AGENT=Mozilla/5.0\ \(Macintosh\;\ Intel\ Mac\ OS\ X\ 10_7_3\)\ AppleWebKit/534.55.3\ \(KHTML,\ like\ Gecko\)\ Version/5.1.5\ Safari/534.55.3; export HTTP_USER_AGENT
HTTP_HOST=xxx.yyyyy.com; export HTTP_HOST
SERVER_PORT=80; export SERVER_PORT
DOCUMENT_ROOT=/home/user/www; export DOCUMENT_ROOT
SCRIPT_FILENAME=/home/user/www/Update/LaunchUpdates.php; export SCRIPT_FILENAME
REQUEST_URI=/Update/LaunchUpdates.php; export REQUEST_URI
SCRIPT_NAME=/Update/LaunchUpdates.php; export SCRIPT_NAME
HTTP_CONNECTION=keep-alive; export HTTP_CONNECTION
REMOTE_PORT=36291; export REMOTE_PORT
PATH=/bin:/usr/bin; export PATH
PWD=/home/user/www/Update; export PWD
SERVER_ADMIN=webmaster@abcdef.com; export SERVER_ADMIN
REDIRECT_STATUS=200; export REDIRECT_STATUS
HTTP_ACCEPT_LANGUAGE=en-us; export HTTP_ACCEPT_LANGUAGE
HTTP_ACCEPT=text/html,application/xhtml+xml,application/xml\;q=0.9,\*/\*\;q=0.8; export HTTP_ACCEPT
REMOTE_ADDR=83.101.41.41; export REMOTE_ADDR
SHLVL=764; export SHLVL
SERVER_NAME=xxx.yyyyy.com; export SERVER_NAME
SERVER_SOFTWARE=Apache/2.2.20\ \(Unix\)\ mod_ssl/2.2.20\ OpenSSL/0.9.8o; export SERVER_SOFTWARE
QUERY_STRING=; export QUERY_STRING
SERVER_ADDR=1.2.3.4; export SERVER_ADDR
GATEWAY_INTERFACE=CGI/1.1; export GATEWAY_INTERFACE
SERVER_PROTOCOL=HTTP/1.1; export SERVER_PROTOCOL
HTTP_ACCEPT_ENCODING=gzip,\ deflate; export HTTP_ACCEPT_ENCODING
REQUEST_METHOD=GET; export REQUEST_METHOD
cd /home/user/www/Update || {
echo 'Execution directory inaccessible' >&2
exit 1
}
/usr/local/php53/bin/php -d memory_limit=512M -q /home/user/www/Update/Update.php;
在等待 2 分钟后重新安排工作时,我得到了新工作的内容,它是相同的,除了:
SHLVL=764 已经变成了 SHLVL=765
更多信息!
正如用户建议的那样,我尝试使用 nohup 而不是 at。所以我做了以下事情:
在 .sh 文件中生成要由 nohup 运行的命令(具有执行权限)。然后执行 exec('nohup .....')
我还在 LaunchUpdates 中添加了一个检查,以确保在 nohup 批处理完成运行之前不会再次调用它(我基本上是 rm .sh 文件及其批处理的结尾,在 LaunchUpdates 中我检查该文件是否存在)。
所以简而言之。
batchProcess.sh 包含:
/usr/local/php53/bin/php -d memory_limit=512M -q /home/user/www/Update/Update.php;
rm /home/user/batchProcess.sh
我的 LaunchUpdates php 代码包含:
$batchFile = "/home/user/batchProcess.sh";
if (file_exists($batchFile))
{
echo 'Process still running. Try again later!';
exit;
}
exec('nohup /home/user/batchProcess.sh > ~/process.out 2> ~/process.err < /dev/null &');
不,会发生什么:
我在我的 php 脚本中注释掉了 exec 行,所以文件不会被执行而是生成。我通过使用 ssh 登录手动测试文件,更改为用户“user”并运行:
nohup /home/user/batchProcess.sh > ~/process.out 2> ~/process.err < /dev/null &
一切正常(最后删除 .sh 文件)!
接下来我取消注释 exec 行并重新运行 php 脚本。process.out 包含:
Process still running. Try again later!
这意味着它再次执行基本脚本而不是执行语句???我完全迷失在这里!由于我在两个帐户上运行相同的 bash 脚本,因此执行哪些命令不会出错。
我应该开始挖掘 apache 日志吗?
这应该需要一点时间,男孩是我错了......