草庐IT

php 长时间运行的进程, 'at' 行为非常奇怪

coder 2023-06-17 原文

首先,我远不是 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!

这意味着它再次执行基本脚本而不是 exec 语句??? 我完全迷失在这里!由于我在这两个帐户上运行相同的 bash 脚本,因此执行的命令不会出错。

我应该开始挖掘 Apache 日志吗?

这本来应该花一点时间,男孩我错了....

最佳答案

由于您示例中的“at”命令用于从调用终端取消绑定(bind)脚本,您可以使用“nohup”而不是“at”。

试试这个(从调用进程中解除绑定(bind),等待 120 秒然后调用 php):

/usr/bin/nohup /bin/sleep 120 2> /dev/null && \
/bin/date >> /tmp/longphp.log && \
/usr/local/php53/bin/php -d memory_limit=512M \
  -q /home/user/www/Update/Update.php >> /tmp/longphp.log 2>> /tmp/longphp.log

它创建/tmp/longphp.log 文件用于分析。 您还可以创建一个包含先前脚本的 shell 包装器以进行简化。

关于php 长时间运行的进程, 'at' 行为非常奇怪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10376143/

有关php 长时间运行的进程, 'at' 行为非常奇怪的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

    我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

  4. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  5. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

  6. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

  7. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  8. ruby - 无法运行 Rails 2.x 应用程序 - 2

    我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby​​:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r

  9. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  10. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

随机推荐