# 用户日志系统进度追踪机制优化 ## 概述 根据用户要求,用户日志系统的进度追踪机制已从使用缓存存储改为通过读取 `user_logs` 表的数据来确定处理进度。这种方式更加可靠和准确。 ## 修改内容 ### 1. 进度追踪方式变更 **原来的方式(使用缓存):** ```php // 从缓存获取进度 $lastProcessedId = Cache::get("user_log_collector:last_processed_id:{$sourceTable}", 0); $lastProcessedTimestamp = Cache::get("user_log_collector:last_processed_timestamp:{$sourceTable}", 0); // 更新进度到缓存 Cache::put("user_log_collector:last_processed_id:{$sourceTable}", $id, 86400); Cache::put("user_log_collector:last_processed_timestamp:{$sourceTable}", $timestamp, 86400); ``` **现在的方式(读取user_logs表):** ```php // 从user_logs表获取最后处理的记录 $lastLog = UserLog::where('source_table', $sourceTable) ->where('source_type', $sourceType) ->orderBy('source_id', 'desc') ->first(); $lastProcessedId = $lastLog ? $lastLog->source_id : 0; ``` ### 2. 核心修改文件 #### BaseLogCollector.php - `getLastProcessedId()`: 改为从user_logs表查询最后处理的source_id - `getLastProcessedTimestamp()`: 改为从user_logs表查询最后处理的时间戳 - `updateLastProcessedId()`: 不再需要手动更新,进度自动追踪 - `updateLastProcessedTimestamp()`: 不再需要手动更新,进度自动追踪 - 添加 `getOriginalRecordTimestamp()` 抽象方法 #### 各收集器实现 - **FundLogCollector**: 添加 `getOriginalRecordTimestamp()` 方法 - **ItemLogCollector**: 添加 `getOriginalRecordTimestamp()` 方法 - **FarmLogCollector**: 添加 `getOriginalRecordTimestamp()` 方法,处理多表情况 #### CollectUserLogsCommand.php - 修改统计功能,从user_logs表读取进度信息 - 修改重置功能,清空user_logs表而不是清除缓存 - 优化错误处理和异常捕获 ### 3. 优势 #### 3.1 数据一致性 - 进度信息直接来源于实际处理结果 - 避免缓存与实际数据不一致的问题 - 重启服务后进度不会丢失 #### 3.2 可靠性 - 不依赖缓存系统的稳定性 - 数据持久化存储,不会因为缓存清理而丢失 - 可以通过数据库查询验证处理进度 #### 3.3 可追溯性 - 可以查看具体的处理历史 - 便于问题排查和数据审计 - 支持按时间范围查询处理记录 ### 4. 实现细节 #### 4.1 进度查询逻辑 ```php protected function getLastProcessedId(): int { try { $lastLog = \App\Module\Game\Models\UserLog::where('source_table', $this->sourceTable) ->where('source_type', $this->sourceType) ->orderBy('source_id', 'desc') ->first(); return $lastLog ? $lastLog->source_id : 0; } catch (\Exception $e) { Log::error("获取最后处理ID失败", [ 'collector' => $this->collectorName, 'source_table' => $this->sourceTable, 'error' => $e->getMessage() ]); return 0; } } ``` #### 4.2 农场收集器特殊处理 由于农场收集器需要处理多个表(farm_harvest_logs 和 farm_upgrade_logs),进度查询逻辑特殊处理: ```php protected function getLastProcessedId(): int { try { // 查询农场相关的最后处理记录 $lastLog = \App\Module\Game\Models\UserLog::where('source_type', $this->sourceType) ->whereIn('source_table', ['farm_harvest_logs', 'farm_upgrade_logs']) ->orderBy('source_id', 'desc') ->first(); return $lastLog ? $lastLog->source_id : 0; } catch (\Exception $e) { return 0; } } ``` #### 4.3 时间戳获取 ```php protected function getOriginalRecordTimestamp(int $recordId): int { try { $record = FundLogModel::find($recordId); return $record ? $record->create_time : 0; } catch (\Exception $e) { return 0; } } ``` ### 5. 计划任务配置 在 `routes/console.php` 中添加了用户日志收集的计划任务: ```php // 每分钟收集用户日志(实现高频收集) \Illuminate\Support\Facades\Schedule::command('game:collect-user-logs --limit=100')->everyMinute(); ``` 虽然无法实现严格的"每2秒"执行,但每分钟执行可以保证较高的实时性。 ### 6. 命令使用 ```bash # 显示收集器信息 php artisan game:collect-user-logs --info # 显示统计信息 php artisan game:collect-user-logs --stats # 执行收集(限制处理记录数) php artisan game:collect-user-logs --limit=100 # 显示详细处理过程 php artisan game:collect-user-logs --detail # 重置进度(清空user_logs表) php artisan game:collect-user-logs --reset ``` ### 7. 注意事项 1. **重置功能**: `--reset` 选项会清空整个user_logs表,请谨慎使用 2. **性能考虑**: 每次查询user_logs表获取进度,在高频执行时需要注意数据库性能 3. **兼容性**: 保留了原有的缓存相关方法,确保向后兼容 4. **错误处理**: 增强了异常处理,避免单个收集器失败影响整体流程 ## 总结 通过这次优化,用户日志系统的进度追踪更加可靠和准确。系统不再依赖缓存存储进度信息,而是直接从实际的处理结果(user_logs表)中获取进度,确保了数据的一致性和可靠性。