【问题标题】:Potential issues with a very long PHP script很长的 PHP 脚本的潜在问题
【发布时间】:2011-11-10 09:59:44
【问题描述】:

我有一个每天运行一次的 PHP 脚本,它需要 30 分钟才能运行(我认为)。一切都是安全可靠的操作。大约 10~15 分钟后,我不断收到 500 错误。但是我在日志等中看不到任何内容,所以我有点困惑。

到目前为止,我设置为“无限”的东西是:

  • max_execution_time
  • max_input_time
  • default_socket_timeout

还将这些设置为仅针对本节(脚本运行所在的文件夹)的高数字

  • memory_limit
  • post_max_size

这个脚本的本质是一个 SOAP 类型的 API,它从 3rd 方 URL 导入数千行数据,将它们放入本地 MySQL 表中,然后下载每一行附加的图像,因此数据量很重要。

我正在尝试找出其他 PHP 变量等。为了完成整个事情,我还缺少什么。我设置的其他 PHP 变量:

  • display_errors = 开启
  • log_errors = 开启
  • error_reporting = E_ALL & ~E_NOTICE & ~E_WARNING
  • error_log = "error_log"

【问题讨论】:

  • 我有一段时间遇到类似的问题,我尝试在浏览器中执行(因为没有安装从命令行执行的功能),但是一旦设置好我就没有问题了。根据您的问题,我不确定您在哪里运行它 - 浏览器或命令行,所以我想我会发表评论。
  • 现在我什至还没有将它作为一项 cron 工作。我正在通过浏览器测试它。
  • 这不是重点。亲爱的主 - 有多少不切实际的书呆子试图争论 Stack Overflow 上哪种语言更好,以换掉该死的灯泡?没有,他们会争论如何发明一个新的光源而不是另一个灯泡......

标签: mysql post soap php


【解决方案1】:

有三种超时:

  1. PHP 级别:set_time_limit
  2. Apache 级别:Timeout
  3. Mysql等级:Mysql Options

在您的情况下,Apache 似乎已超时。在这种情况下,最好使用 PHP CLI。但是如果你真的需要实时做这个操作。然后你可以使用Gearman,通过它你将在PHP中实现真正的并行。

如果您需要从普通 HTTP 请求(浏览器->Apache)触发脚本的简单解决方案,您可以将后端脚本(CLI 脚本)作为 shell 命令从 PHP 但“异步”运行。更多信息可以在Asynchronous shell exec in PHP找到。

【讨论】:

  • apache 选项 - 我可以覆盖它吗?我可以把它放在.htaccess 下吗?还是我应该在 WHM 中进行?
  • 当我将 Timeout 3600 放在 .htaccess 中时,它导致了另一个内部服务器错误 :( 我在 WHM 部分有这个覆盖,但我想知道我是否可以将它限制在我的这个域中?我运行专用服务器。
  • 其实你可以这样做,但我不推荐。您不希望有长时间运行的脚本会占用您的服务器内存并有许多 apache 进程等待如此长的脚本。最好的办法是使用 PHP CLI。但是,如果您想从普通的 HTTP 请求(浏览器/Apache)触发脚本,您可以从 PHP 运行“类异步”shell exec。更多信息可以在stackoverflow.com/questions/222414/…中找到
  • 我认为问题是超时 - 我让我的服务器管理员更改了该帐户 httpd.conf 中的超时指令,这很好。那里没有运行太长的其他功能(除了我自己的东西通过安全标签访问),所以 tiemout 对这个来说不是问题。
【解决方案2】:

尝试使用 PHP 命令行界面 (php-cli) 来完成冗长的任务。除非您设置/终止它,否则命令行中的执行时间是无限的。您也可以通过 cron 作业设置时间表。

【讨论】:

    【解决方案3】:

    用 PHP 从命令行运行它(例如php yourscript.php),这个错误应该不会发生。此外,使用set_time_limit(0) 也不是一个好主意;你最多应该使用set_time_limit(86400)。您可以将 cron 作业设置为每天执行一次。只需确保脚本中的所有文件路径都是绝对的而不是相对的,以免混淆。

    编译脚本也可能会有所帮助。 HipHop 是一个很棒的 PHP 编译器,然后你的脚本会运行得更快,使用更少的内存,并且可以使用尽可能多的资源。 HipHop 只是很难安装。

    【讨论】:

    • “它是一个导入数千行数据的 SOAP 类型的 API”。在这种情况下,我预计网络是瓶颈,因此 hiphop 提供的好处很少。
    【解决方案4】:

    如果执行时间有问题,那么也许你应该在脚本中使用set_time_limit 函数设置max_execution 时间:

    set_time_limit(0);
    

    我也会直接使用 php 在命令行上调用脚本,而不是通过 apache。此外,打印出一些状态消息,并将它们通过管道传输到日志中。

    我怀疑您的实际问题是脚本在某处因错误数据而窒息。

    【讨论】:

    • 我也已经设置了该命令。如果它是你描述的错误,当我通过浏览器运行它时它不会出现吗? display_errors = On log_errors = On error_reporting = E_ALL & ~E_NOTICE & ~E_WARNING error_log = "error_log"
    • 显然它没有出现,或者你会看到它。这可能是一个逻辑错误,这就是您应该打印常规状态消息的原因。然后运行命令行,看看你得到了什么。
    • 我会再次检查日志...每个数据条目都会记录 ID # 等,但最后我检查它们只是停止了,好像结束了一样。
    • 因此,请看一下它停止之前和之后的条目。然后看看他们会对代码做什么。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-24
    • 1970-01-01
    • 1970-01-01
    • 2011-07-10
    • 1970-01-01
    相关资源
    最近更新 更多