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

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 自动扣款任务诊断报告
## 问题描述
`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. ⏳ 确认任务正常执行