| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323 |
- <?php
- namespace App\Module\OpenAPI\Commands;
- use App\Module\OpenAPI\Models\OpenApiLog;
- use App\Module\OpenAPI\Models\OpenApiRateLimit;
- use App\Module\OpenAPI\Models\OpenApiStats;
- use App\Module\OpenAPI\Services\RateLimitService;
- use Illuminate\Console\Command;
- use Carbon\Carbon;
- /**
- * 清理OpenAPI数据命令
- */
- class CleanDataCommand extends Command
- {
- /**
- * 命令签名
- *
- * @var string
- */
- protected $signature = 'openapi:clean-data
- {--logs=30 : 保留日志天数}
- {--rate-limits=7 : 保留限流记录天数}
- {--stats=365 : 保留统计数据天数}
- {--dry-run : 仅显示将要删除的数据,不实际删除}
- {--force : 强制删除,不询问确认}';
- /**
- * 命令描述
- *
- * @var string
- */
- protected $description = '清理OpenAPI过期数据';
- protected RateLimitService $rateLimitService;
- /**
- * 构造函数
- *
- * @param RateLimitService $rateLimitService
- */
- public function __construct(RateLimitService $rateLimitService)
- {
- parent::__construct();
- $this->rateLimitService = $rateLimitService;
- }
- /**
- * 执行命令
- *
- * @return int
- */
- public function handle(): int
- {
- $logsDays = (int)$this->option('logs');
- $rateLimitDays = (int)$this->option('rate-limits');
- $statsDays = (int)$this->option('stats');
- $dryRun = $this->option('dry-run');
- $force = $this->option('force');
- $this->info('OpenAPI数据清理工具');
- $this->line('');
- // 显示清理计划
- $this->table(['数据类型', '保留天数', '清理日期之前'], [
- ['API调用日志', $logsDays, Carbon::now()->subDays($logsDays)->toDateString()],
- ['限流记录', $rateLimitDays, Carbon::now()->subDays($rateLimitDays)->toDateString()],
- ['统计数据', $statsDays, Carbon::now()->subDays($statsDays)->toDateString()],
- ]);
- if ($dryRun) {
- $this->warn('这是一次试运行,不会实际删除数据');
- }
- // 统计将要删除的数据
- $logsCount = $this->getExpiredLogsCount($logsDays);
- $rateLimitsCount = $this->getExpiredRateLimitsCount($rateLimitDays);
- $statsCount = $this->getExpiredStatsCount($statsDays);
- $this->line('');
- $this->info('将要清理的数据统计:');
- $this->table(['数据类型', '记录数'], [
- ['API调用日志', number_format($logsCount)],
- ['限流记录', number_format($rateLimitsCount)],
- ['统计数据', number_format($statsCount)],
- ]);
- if ($logsCount === 0 && $rateLimitsCount === 0 && $statsCount === 0) {
- $this->info('没有需要清理的数据');
- return 0;
- }
- // 确认删除
- if (!$dryRun && !$force) {
- if (!$this->confirm('确定要删除这些数据吗?此操作不可恢复!')) {
- $this->info('操作已取消');
- return 0;
- }
- }
- $this->line('');
- $this->info('开始清理数据...');
- $totalDeleted = 0;
- // 清理API调用日志
- if ($logsCount > 0) {
- $deleted = $this->cleanLogs($logsDays, $dryRun);
- $totalDeleted += $deleted;
- $this->line("✓ 清理API调用日志: " . number_format($deleted) . " 条记录");
- }
- // 清理限流记录
- if ($rateLimitsCount > 0) {
- $deleted = $this->cleanRateLimits($rateLimitDays, $dryRun);
- $totalDeleted += $deleted;
- $this->line("✓ 清理限流记录: " . number_format($deleted) . " 条记录");
- }
- // 清理统计数据
- if ($statsCount > 0) {
- $deleted = $this->cleanStats($statsDays, $dryRun);
- $totalDeleted += $deleted;
- $this->line("✓ 清理统计数据: " . number_format($deleted) . " 条记录");
- }
- $this->line('');
- if ($dryRun) {
- $this->info("试运行完成,共计将删除 " . number_format($totalDeleted) . " 条记录");
- } else {
- $this->info("数据清理完成,共删除 " . number_format($totalDeleted) . " 条记录");
- }
- return 0;
- }
- /**
- * 获取过期日志数量
- *
- * @param int $days
- * @return int
- */
- protected function getExpiredLogsCount(int $days): int
- {
- $cutoffDate = Carbon::now()->subDays($days);
- return OpenApiLog::where('created_at', '<', $cutoffDate)->count();
- }
- /**
- * 获取过期限流记录数量
- *
- * @param int $days
- * @return int
- */
- protected function getExpiredRateLimitsCount(int $days): int
- {
- $cutoffDate = Carbon::now()->subDays($days);
- return OpenApiRateLimit::where('created_at', '<', $cutoffDate)->count();
- }
- /**
- * 获取过期统计数据数量
- *
- * @param int $days
- * @return int
- */
- protected function getExpiredStatsCount(int $days): int
- {
- $cutoffDate = Carbon::now()->subDays($days);
- return OpenApiStats::where('created_at', '<', $cutoffDate)->count();
- }
- /**
- * 清理API调用日志
- *
- * @param int $days
- * @param bool $dryRun
- * @return int
- */
- protected function cleanLogs(int $days, bool $dryRun): int
- {
- $cutoffDate = Carbon::now()->subDays($days);
-
- if ($dryRun) {
- return OpenApiLog::where('created_at', '<', $cutoffDate)->count();
- }
- $deleted = 0;
- $batchSize = 1000;
- // 分批删除,避免内存溢出
- do {
- $deletedBatch = OpenApiLog::where('created_at', '<', $cutoffDate)
- ->limit($batchSize)
- ->delete();
-
- $deleted += $deletedBatch;
-
- if ($deletedBatch > 0) {
- $this->line(" 已删除 {$deleted} 条日志记录...");
- }
-
- } while ($deletedBatch > 0);
- return $deleted;
- }
- /**
- * 清理限流记录
- *
- * @param int $days
- * @param bool $dryRun
- * @return int
- */
- protected function cleanRateLimits(int $days, bool $dryRun): int
- {
- if ($dryRun) {
- $cutoffDate = Carbon::now()->subDays($days);
- return OpenApiRateLimit::where('created_at', '<', $cutoffDate)->count();
- }
- // 使用服务类的清理方法
- return $this->rateLimitService->cleanExpiredRecords($days);
- }
- /**
- * 清理统计数据
- *
- * @param int $days
- * @param bool $dryRun
- * @return int
- */
- protected function cleanStats(int $days, bool $dryRun): int
- {
- $cutoffDate = Carbon::now()->subDays($days);
-
- if ($dryRun) {
- return OpenApiStats::where('created_at', '<', $cutoffDate)->count();
- }
- $deleted = 0;
- $batchSize = 1000;
- // 分批删除
- do {
- $deletedBatch = OpenApiStats::where('created_at', '<', $cutoffDate)
- ->limit($batchSize)
- ->delete();
-
- $deleted += $deletedBatch;
-
- if ($deletedBatch > 0) {
- $this->line(" 已删除 {$deleted} 条统计记录...");
- }
-
- } while ($deletedBatch > 0);
- return $deleted;
- }
- /**
- * 清理缓存数据
- *
- * @return void
- */
- protected function cleanCache(): void
- {
- $this->info('清理缓存数据...');
-
- // 清理限流缓存
- $pattern = 'rate_limit:*';
- $keys = \Illuminate\Support\Facades\Cache::getRedis()->keys($pattern);
-
- if (!empty($keys)) {
- \Illuminate\Support\Facades\Cache::getRedis()->del($keys);
- $this->line("✓ 清理限流缓存: " . count($keys) . " 个键");
- }
- // 清理应用缓存
- $pattern = 'openapi_app:*';
- $keys = \Illuminate\Support\Facades\Cache::getRedis()->keys($pattern);
-
- if (!empty($keys)) {
- \Illuminate\Support\Facades\Cache::getRedis()->del($keys);
- $this->line("✓ 清理应用缓存: " . count($keys) . " 个键");
- }
- // 清理权限缓存
- $pattern = 'app_scopes:*';
- $keys = \Illuminate\Support\Facades\Cache::getRedis()->keys($pattern);
-
- if (!empty($keys)) {
- \Illuminate\Support\Facades\Cache::getRedis()->del($keys);
- $this->line("✓ 清理权限缓存: " . count($keys) . " 个键");
- }
- }
- /**
- * 优化数据库表
- *
- * @return void
- */
- protected function optimizeTables(): void
- {
- $this->info('优化数据库表...');
-
- $tables = [
- 'kku_openapi_logs',
- 'kku_openapi_rate_limits',
- 'kku_openapi_stats',
- ];
- foreach ($tables as $table) {
- try {
- \Illuminate\Support\Facades\DB::statement("OPTIMIZE TABLE {$table}");
- $this->line("✓ 优化表: {$table}");
- } catch (\Exception $e) {
- $this->warn("优化表 {$table} 失败: " . $e->getMessage());
- }
- }
- }
- }
|