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.
3.7 KiB
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')
可能的原因总结
-
调度器未运行(最可能)
- crontab 未配置或配置错误
- 服务器时间不正确
- 调度器进程被杀死
-
代码执行异常
- 数据库连接问题
- 数据完整性问题(customer 为 null)
- 其他运行时错误
-
时间范围问题
- 任务只在 14:00-23:59 之间执行
- 如果当前时间不在这个范围内,任务不会执行
-
没有待处理的订单
- 所有订单都已处理
- 查询条件不匹配
建议的监控措施
-
添加任务执行监控
- 可以添加一个健康检查接口
- 记录最后一次成功执行的时间
-
设置告警
- 如果超过一定时间没有执行,发送告警
- 监控日志中的错误数量
-
定期检查
- 定期检查日志文件
- 确认任务正常执行
改进后的代码位置
app/Models/OrderItems.php-autoCheckout()方法app/Console/Kernel.php- 调度器配置
下一步行动
- ✅ 已添加异常处理和详细日志
- ⏳ 检查并配置 Laravel 调度器
- ⏳ 查看改进后的日志输出
- ⏳ 确认任务正常执行