驻足生活 2025-01-21 16:09 采纳率: 22.2%
浏览 4

对失败数据进行计划任务的多次处理和反馈

有一个场景,要写一个对失败的数据进行二次请求的任务任务。

失败数据来源。队列中执行,一条处理时间为两秒。设置的计划任务处理失败的每十秒执行一次。

牵扯到表中有三个字段,status:1:成功,2:失败,next_cron_time:下次执行时间,cron_num:已执行次数,默认0;

首先从表中读取status=2(失败)的数据,进行再次请求,如果成功,更新status=1,如果失败,更新next_cron_time为24小时之后,并且corn_num+1,当corn_num > 7的时候,不在进行重新请求了,连续七次失败,再请求也没意义了。

由于失败的数据量比较大,现在有两个问题。


 $order = 'cron_num asc,id asc';
 $order = 'cron_num desc,next_cron_time desc,id asc';
$where = [
            ['status','=',2],
            ['cron_num','<',8],//处理7次,每次失败后24小时继续执行下一次
            ['next_cron_time','<',date('Y-m-d H:i:s',time())],
        ];
$info = (new FlowWorkModel())->order($order)->where($where)->field($field)->find();

$order = 'cron_num asc,id asc';:因为失败的次数比较多,如果按照'cron_num asc排序的话,有可能设置了下次执行时间的数据一直都达不到,因为失败的数据一直在增加,一直在处理新的失败的。
$order = 'cron_num desc,next_cron_time desc,id asc';:如果是这种的话,那刚开始失败的又很难再执行到第二遍。
有没有更巧妙的办法啊

  • 写回答

3条回答 默认 最新

  • 关注

    以下回复参考:皆我百晓生券券喵儿等免费微信小程序作答:

    针对你的问题,你可以考虑使用优先级队列的方式来处理失败的数据。这种方法可以确保在处理失败数据时,既考虑到失败次数,又考虑到下次执行的时间。

    以下是一个可能的解决方案:

    1. 创建一个优先级队列,根据失败次数和下次执行时间来决定任务的优先级。
    2. 当从数据库中获取失败任务时,首先根据next_cron_time进行排序,确保先处理那些时间较早的任务。
    3. 在处理完这些任务后,对于那些仍然失败的任务,根据cron_num进行排序,优先处理失败次数较少的任务。
    4. 当一个任务连续失败达到设定的最大尝试次数(例如7次)时,将其标记为不再尝试,或者将其放入一个不再尝试的队列中,避免再次被处理。

    具体实现如下:

    // 从数据库中获取失败任务
    $where = [
        ['status', '=', 2],
        ['cron_num', '<', 8], // 处理7次,每次失败后24小时继续执行下一次
        ['next_cron_time', '<=', date('Y-m-d H:i:s', time())] // 修改为小于等于当前时间,确保获取到的任务可以立即处理
    ];
    $orders = [
        ['next_cron_time', 'asc'], // 先处理时间较早的任务
        ['cron_num', 'asc'] // 对于时间相同的任务,优先处理失败次数较少的任务
    ];
    $info = (new FlowWorkModel())->order($orders)->where($where)->field($field)->select();
    
    // 处理获取到的任务
    foreach ($info as $task) {
        // 进行再次请求
        if ($task['status'] == 2) { // 仅处理失败的任务
            // 执行你的再次请求逻辑
            // 如果成功,更新状态为1;如果失败,更新next_cron_time和corn_num
        } else { // 对于达到最大尝试次数的任务,可以将其放入不再尝试的队列或直接跳过处理
            // 进行相应的处理,例如将其标记为不再尝试或放入另一个队列中
        }
    }
    

    通过这种方式,你可以确保在处理失败数据时既考虑到时间因素,又考虑到失败次数。同时,对于连续失败达到设定次数的任务,可以进行特殊处理,避免无意义的重复请求。

    评论

报告相同问题?

问题事件

  • 创建了问题 1月21日