【问题标题】:How to handle a Beanstalkd job that has an error如何处理有错误的 Beanstalkd 作业
【发布时间】:2026-01-21 02:40:02
【问题描述】:

当我的 Beanstalkd 作业出现错误时,例如 "exception 'ErrorException' with message 'Notice: Undefined index: id in /var/www/mysite/app/libraries/lib.php line 248' in /var/www/mysite/app/libraries/lib.php:248,Beanstalkd 应该如何知道发生了错误并将其标记为失败以便可以再次重试?

【问题讨论】:

  • 这不是错误,它是通知。当您尝试使用未分配的变量时会发生这种情况。
  • 在这种情况下,函数会异常退出。作业是否标记为已完成?还是返回就绪状态?

标签: php queue laravel laravel-4 beanstalkd


【解决方案1】:

为 beanstalkd 安装一个监视器,这在开发/测试您的应用程序时很有用。一些使用 PHP 的替代方案:http://mnapoli.github.io/phpBeanstalkdAdmin/https://github.com/ptrofimov/beanstalk_console

至于处理错误,您可以为 beanstalkd 作业定义自己的错误处理程序,并在该处理程序中决定是否要:

  • 埋葬(将工作搁置以备日后检查)
  • 踢(放回队列)
  • 删除(删除它,如果这对您的应用程序是安全的)

编辑 - 你设法解决了你的问题吗? 最好的方法可能是在您的工作周围使用 try/catch 来捕获异常,然后在工作人员引发异常时将其掩埋。如果在生产者处引发异常,它可能永远不会添加到队列中,因此不需要 bury() ,但使用监视器来确保。

如果你想尝试为你的对象定义一个自己的错误处理程序,我之前做过类似的事情,为你的类设置一个自定义错误处理程序。尝试通过 $errcontext 获取 pheanstalk (作业)对象可能是一个丑陋的 hack - 但可能是要尝试的东西。如果你想尝试一下,这是我快速整理的一些伪代码(创建了一个子类避免将代码放入 pheanstalk 类):

class MyPheanstalk extends Pheanstalk {

    function __construct() {
        //register your custom error_handler for objects of this class
        set_error_handler(array($this, 'myPheanstalk_error_handler'));

        //call parent constructor
        parent::__construct();
    }

    function myPheanstalk_error_handler($errno, $errstr, $errfile, $errline, $errcontext) {
        // get the current job that failed
        foreach($errcontext as $val) //print_r($errcontext) to find info on the object(job) you are looking for
        {
            if(is_object($val)) {
                if(get_class($val) == 'Pheanstalk') { //and replace with correct class here
                    //optionally check errstr to decide if you want to delete() or kick() instead of bury()
                    $this->bury($val);
                }
            }
        }
    }
}

【讨论】:

    【解决方案2】:

    出错的是你的脚本,而不是 beanstalkd。

    try { 
    
    //your code from Line 248 here
    
    } catch (ErrorException $e) { //this section catches the error.
    
    //you can print the error
    echo 'An error occurred'. $e->getMessage();
    //or do something else like try reporting the ID is bad.
    
    if (!isset($id)) {
    echo 'The id was not set!';
    }
    
    
    } //end of try/catch
    

    【讨论】: