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

142 lines
3.7 KiB

4 months ago
# 自动扣款任务诊断报告
## 问题描述
`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 调度器是否运行**
```bash
# 检查 crontab 是否配置了调度器
crontab -l | grep "schedule:run"
# 应该看到类似这样的配置:
# * * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
```
如果没有配置,需要添加:
```bash
* * * * * cd /Users/weizongsong/www/tiantian2 && php artisan schedule:run >> /dev/null 2>&1
```
### 2. **检查调度器状态**
```bash
# 查看调度器列表
php artisan schedule:list
# 手动运行一次调度器(测试)
php artisan schedule:run
```
### 3. **检查日志文件**
```bash
# 查看最新的自动扣款日志
ls -lah storage/logs/daily_auto_checkout*.log
# 查看日志内容
tail -f storage/logs/daily_auto_checkout-$(date +%Y-%m-%d).log
```
### 4. **手动测试任务**
```bash
# 在 PHP 交互式环境中测试
php artisan tinker
>>> (new \App\Models\OrderItems())->autoCheckout();
```
### 5. **检查缓存**
```bash
# 检查缓存中的 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. ⏳ 确认任务正常执行