redis-queue 队列插件能不能主动抛出异常?

kspade

https://www.workerman.net/plugin/12
下面是webman 官方插件的一些说明:

消费失败重试
如果消费失败(发生了异常),则消息会放入延迟队列,等待下次重试。重试次数通过参数 max_attempts 控制,重试间隔由
retry_seconds 和 max_attempts共同控制。比如max_attempts为5,retry_seconds为10,第1次重试间隔为1*10秒,第2次重试时间间隔为 2*10秒,第3次重试时间间隔为3*10秒,以此类推直到重试5次。如果超过了max_attempts设置测重试次数,则消息放入key为{redis-queue}-failed的失败队列。

注意
消费过程中没有抛出异常视为消费成功,否则消费失败,进入重试队列

问题

因为redis没有ack 模式,
1.能否故意把某个队列抛出为异常(目的是为了丢进重试队列)
2.又或者能不能主动把某条队列丢入重试队列

原因

因为我的队列消费时的工作场景为:curl 携带XX参数,访问一个异步通知地址,当整个地址返回的内容为:success 代表消费成功,否则丢入重试队列(xx秒后重试 - 一共重试5次)

rabbitmq 的stomp是符合我的使用场景的,搞了两天了都没搞定这玩意 太难了!
什么都搞好了,投递消息就提示:Stomp client: not_found
放弃了 搞redis-queue

1133 4 0
4个回答

2548a

使用 throw new \Exception();不就好了吗

  • kspade 2022-05-22

    public function consume 里面 怎么使用哦

  • 2548a 2022-05-22

    判断返回地址,不符合要求就调用 throw new \Exception('xx不符合,重试'); 就完了,这句话就是手动抛异常的.这样它就会判断队列执行失败,等会就会再重新执行了

  • kspade 2022-05-22

    我试了一下并不行,产生一堆垃圾信息

    0 /log/webman/vendor/workerman/redis-queue/src/Client.php(218): app\queue\redis\MyMailSend->consume()

    1 /log/webman/vendor/workerman/redis/src/Client.php(422): Workerman\RedisQueue\Client->Workerman\RedisQueue{closure}()

    2 /log/webman/vendor/workerman/workerman/Connection/TcpConnection.php(638): Workerman\Redis\Client->Workerman\Redis{closure}()

    3 [internal function]: Workerman\Connection\TcpConnection->baseRead()

    4 /log/webman/vendor/workerman/workerman/Events/Event.php(193): EventBase->loop()

    5 /log/webman/vendor/workerman/workerman/Worker.php(2435): Workerman\Events\Event->loop()

    6 /log/webman/vendor/workerman/workerman/Worker.php(1555): Workerman\Worker->run()

    7 /log/webman/vendor/workerman/workerman/Worker.php(1397): Workerman\Worker::forkOneWorkerForLinux()

    8 /log/webman/vendor/workerman/workerman/Worker.php(1371): Workerman\Worker::forkWorkersForLinux()

    9 /log/webman/vendor/workerman/workerman/Worker.php(1692): Workerman\Worker::forkWorkers()

    10 /log/webman/vendor/workerman/workerman/Worker.php(1641): Workerman\Worker::monitorWorkersForLinux()

    11 /log/webman/vendor/workerman/workerman/Worker.php(551): Workerman\Worker::monitorWorkers()

    12 /log/webman/start.php(108): Workerman\Worker::runAll()

  • damao 2022-05-23

    可以的,如果发生异常会显示异常包括调用栈,然后自动扔到重试队列里。你贴的这个就是显示的异常信息

nitron

我给个思路吧,也是现在在用的,不使用提供的失败队列,没有得到需要的结果重新将任务发送到队列内,如果执行有异常则catch住后重新将任务发送到队列内,自己记数,超过了设定的次数都未得到需要的结果则丢弃(即不再送入队列),同时记录日志,通知系统有处理失败的任务

  • 暂无评论
yzh52521
 // 队列名
    public $queue = '/topic/send_mail';

    // 连接名,对应 config/redis_queue.php 里的连接`
    public $connection = 'default';

    // 消费
    public function consume($data)
    {
        // 无需反序列化
        //var_export($data); // 输出 ['to' => 'tom@gmail.com', 'content' => 'hello']
        throw new \Exception('异常消息');
    }
  • 暂无评论
evilk

我现在的做法是:
1.
在消费过程中,如果失败了,则手动抛出异常,让该任务进入原队列,等待重新执行

2.
如果最终超过重试次数,则进入失败队列

3.
为了防止失败队列中的任务堆积 和 监控失败的任务
在整个服务启动的时候,单独起一个自定义进程
在进程启动的时候,开启一个定时器
每5秒(时间自定义,我目前设置的是每5秒执行一次),从失败队列中,取出一个失败的任务
把这个任务所有的数据(包括任务本身 和 异常堆栈),入库(一个专门存放失败任务的表)

4.
在后台,开一个页面,可以看到这个表里的数据,也就是所有失败的任务
在这个页面,根据任务失败的原因,可以选择

  • 重新丢入原队列执行
  • 删除该任务
  • 暂无评论
年代过于久远,无法发表回答
🔝