You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
v2.tiantianxinye.365care/自动扣款任务诊断报告.md

3.7 KiB

自动扣款任务诊断报告

问题描述

admin/project 页面的自动扣款任务(autoCheckout)有两天没有按照预期得到结果。

发现的问题

1. 日志文件缺失

  • 最新的日志文件是 storage/logs/daily_auto_checkout-2021-04-11.log
  • 说明最近没有执行记录,可能的原因:
    • Laravel 调度器没有运行
    • 任务执行时发生异常但没有记录

2. 代码缺少异常处理

  • 原代码中 autoCheckout() 方法没有 try-catch 包裹
  • 如果执行过程中出现异常,会导致任务静默失败,且没有错误日志

3. 潜在的空指针问题

  • 代码中 $customer = $item->customer 可能为 null
  • 如果 customer 为 null访问 $customer->balance 会导致致命错误

4. 缺少详细的执行日志

  • 原代码只在开始和成功时记录日志
  • 缺少失败、跳过等情况的详细记录

已实施的改进

1. 添加完整的异常处理

  • autoCheckout() 方法外层添加 try-catch
  • 在调度器调用处也添加异常处理
  • 所有异常都会记录到日志

2. 添加空值检查

  • 检查 $customer 是否为 null
  • 如果为空,记录警告日志并跳过该订单项

3. 增强日志记录

  • 记录任务开始和结束
  • 记录处理的订单项数量
  • 记录成功、跳过、失败的统计
  • 记录每个订单项的详细处理情况
  • 异常时记录完整的堆栈跟踪

4. 添加数据库事务

  • 每个订单项的扣款操作使用事务包裹
  • 确保数据一致性

排查步骤

1. 检查 Laravel 调度器是否运行

# 检查 crontab 是否配置了调度器
crontab -l | grep "schedule:run"

# 应该看到类似这样的配置:
# * * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1

如果没有配置,需要添加:

* * * * * cd /Users/weizongsong/www/tiantian2 && php artisan schedule:run >> /dev/null 2>&1

2. 检查调度器状态

# 查看调度器列表
php artisan schedule:list

# 手动运行一次调度器(测试)
php artisan schedule:run

3. 检查日志文件

# 查看最新的自动扣款日志
ls -lah storage/logs/daily_auto_checkout*.log

# 查看日志内容
tail -f storage/logs/daily_auto_checkout-$(date +%Y-%m-%d).log

4. 手动测试任务

# 在 PHP 交互式环境中测试
php artisan tinker
>>> (new \App\Models\OrderItems())->autoCheckout();

5. 检查缓存

# 检查缓存中的 last_id
php artisan tinker
>>> cache('last_auto_checkout_order_item_id')

可能的原因总结

  1. 调度器未运行(最可能)

    • crontab 未配置或配置错误
    • 服务器时间不正确
    • 调度器进程被杀死
  2. 代码执行异常

    • 数据库连接问题
    • 数据完整性问题customer 为 null
    • 其他运行时错误
  3. 时间范围问题

    • 任务只在 14:00-23:59 之间执行
    • 如果当前时间不在这个范围内,任务不会执行
  4. 没有待处理的订单

    • 所有订单都已处理
    • 查询条件不匹配

建议的监控措施

  1. 添加任务执行监控

    • 可以添加一个健康检查接口
    • 记录最后一次成功执行的时间
  2. 设置告警

    • 如果超过一定时间没有执行,发送告警
    • 监控日志中的错误数量
  3. 定期检查

    • 定期检查日志文件
    • 确认任务正常执行

改进后的代码位置

  • app/Models/OrderItems.php - autoCheckout() 方法
  • app/Console/Kernel.php - 调度器配置

下一步行动

  1. 已添加异常处理和详细日志
  2. 检查并配置 Laravel 调度器
  3. 查看改进后的日志输出
  4. 确认任务正常执行