coolseven / notes

笔记与心得
MIT License
510 stars 188 forks source link

其他问题我都解决了,现在就差queue_failed #1

Open he426100 opened 7 years ago

he426100 commented 7 years ago

感谢楼主的笔记, 当初就想用think-queue,结果完全看不懂,还好现在入门级的操作会搞了。 任务失败始终没有进入我自己的处理, 按你的方法把queue.failed改成queue_failed也是没用哦

he426100 commented 7 years ago

楼主笔记记得非常详细,几乎是手把手的教读者, 要不送佛送到西, 把supervisor怎么配也全程贴出来? 我现在会使用supervisor来管理think-queue了,花了好几个小时才配好

coolseven commented 7 years ago

@he426100 当任务因为超出最大尝试次数而失败时,thinkphp-queue 这个库只是触发了名为 ‘queue.failed’ 的失败事件,但是库本身并没有内置失败事件的处理。如果想要捕捉该事件的话需要开发者手动在 application\tags.php 配置文件中添加 ‘queue.failed’ 事件。 举例:

定义事件

    // 任务失败回调
    'queue.failed'=> [
         'application\\behavior\\MyQueueFailedLogger::logAllFailedQueues',
    ]

处理事件

class MyQueueFailedLogger {
    /**
     * @param $params   \think\queue\Job
     *
     */
    public static function logAllFailedQueues(&$params){
        $failedLog = [
            'jobName'   => $params->getName(),
            'queueName' => $params->getQueue(),
            'rawBody'   => $params->getRawBody(),
            'attempts'  => $params->attempts(),
        ];
        var_export(json_encode($failedLog,true));   
    }
}

补充:

这个笔记是针对 thinkphp-queue 的 v1.1.2 版本写的, 现在(2017-03-04)它的版本已经升级到 v1.1.3 了。这个新版本中,对于失败事件的处理逻辑上官方做了一个好的改动: thinkphp-queue 会先删除任务,调用其 failed 方法, 然后才触发这个事件。 所以我们在这个事件中只需要安心记录一下日志就好了,不再需要像 版本 v1.1.2 中那样操心究竟应该在哪一层去删除任务的问题。 而且如果你打算在每个消费者类的failed 方法中单独去做日志记录,那么这个事件不定义也行 :) 希望对你有帮助。

coolseven commented 7 years ago

@he426100 supervisor 这个软件我还暂时没有接触:) 你可以咨询一下你们公司的运维,他们给出的建议应该比较专业。 也期待你能把 supervisor 的使用笔记分享一下。

he426100 commented 7 years ago

我是照着这个教程搞得,服务器是阿里云的centos7.2,幸运的是非常顺利就装好了 http://www.cnblogs.com/justphp/p/6120201.html

我现在在使用 [program:doulishuju_queue_notify] command=php think queue:work --queue notify --daemon --tries 10 ; 被监控进程 directory=/mnt/wwwroot/www.x.com ;process_name=%(process_num)02d ;numprocs=5 #启动几个进程 autostart=true ;随着supervisord的启动而启动 autorestart=true ;自动启动 startsecs=1 ;程序重启时候停留在runing状态的秒数 startretries=10 ;启动失败时的最多重试次数 redirect_stderr=true ;重定向stderr到stdout user=www ; stdout_logfile=/mnt/wwwroot/www.x.com/runtime/log/supervisor.log ;stdout文件

已经稳定运行一天

coolseven commented 7 years ago

@he426100 如果不改动他默认的 'queue.failed' 事件名,那么 tags.php 中配置该事件时:

   'queue.failed' => [
      // 如果你的写法是下面这种 '类名' 形式的字符串,那么记得给  MyQueueFailedLogger 类添加一个 run 方法。
       'application\\behavior\\MyQueueFailedLogger' ,
   ]

'queue.failed' 其实也不算是什么bug,改成 ‘queue_failed’ 更符合他们自己定义的事件命名规范而已。 官方的事件命名规范在这里: http://www.kancloud.cn/manual/thinkphp5/118130

coolseven commented 7 years ago

@he426100 感谢提供 supervisor 的使用经验。

he426100 commented 7 years ago

那个failed不好用, 我懒得去猜, 干脆自己处理吧, 我也就一个队列, 在fire方法里面首先执行任务, 如果执行失败,判断执行次数, 达到最大次数后调用failed方法

coolseven commented 7 years ago

@he426100 这样也挺好 :) 或者可以参考一下laravel 的做法,把失败的任务转移到 另外的表中。

he426100 commented 7 years ago

装好supervisor后编辑 /etc/supervisord.conf,在文件末尾追加我上面写的那些配置就可以跑了 h 7v9h ri2tp 1d3ce 7em

嗯, 有空我再看看, 非常感谢你的笔记, 我一直想用队列的, 但是我一点不懂, 还好你写的特别详细

coolseven commented 7 years ago

@he426100 ,好的,非常感谢提供。