From e0d43307617c63464931a4d27b287a3318eabff9 Mon Sep 17 00:00:00 2001 From: jonathang4 Date: Thu, 28 Aug 2025 22:26:59 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/controllers/upload.ts | 2 +- src/lib/services/DatabaseGenerationService.ts | 36 +++++++++++++++++++ src/lib/services/TaskPollingService.ts | 12 +++---- src/lib/tos/tos-client.ts | 10 +++--- 4 files changed, 48 insertions(+), 12 deletions(-) diff --git a/src/api/controllers/upload.ts b/src/api/controllers/upload.ts index 484330b..4be0b15 100644 --- a/src/api/controllers/upload.ts +++ b/src/api/controllers/upload.ts @@ -245,7 +245,7 @@ async function requestUpload( ...(options.params || {}), }, headers: h, - timeout: 15000, + timeout: 60000, // 增加超时时间到60秒,匹配客户端期望 validateStatus: () => true, ..._.omit(options, "params", "headers"), }); diff --git a/src/lib/services/DatabaseGenerationService.ts b/src/lib/services/DatabaseGenerationService.ts index b6b671b..cf0a7ed 100644 --- a/src/lib/services/DatabaseGenerationService.ts +++ b/src/lib/services/DatabaseGenerationService.ts @@ -11,9 +11,17 @@ import logger from '@/lib/logger.js'; export class DatabaseGenerationService { private static instance: DatabaseGenerationService; private currentServerId: string; + private resultCache: Map = new Map(); + private taskStatusCache: Map = new Map(); + private readonly CACHE_TTL = 30000; // 30秒缓存 private constructor() { this.currentServerId = process.env.SERVICE_ID || 'jimeng-free-api'; + + // 定期清理过期缓存 + setInterval(() => { + this.cleanExpiredCache(); + }, 60000); // 每分钟清理一次 } public static getInstance(): DatabaseGenerationService { @@ -157,12 +165,40 @@ export class DatabaseGenerationService { } } + /** + * 清理过期缓存 + */ + private cleanExpiredCache(): void { + const now = Date.now(); + + // 清理结果缓存 + for (const [key, value] of this.resultCache.entries()) { + if (now - value.timestamp > this.CACHE_TTL) { + this.resultCache.delete(key); + } + } + + // 清理任务状态缓存 + for (const [key, value] of this.taskStatusCache.entries()) { + if (now - value.timestamp > this.CACHE_TTL) { + this.taskStatusCache.delete(key); + } + } + } + /** * 查询任务结果 * 从结果表查询,如果存在则返回结果并标记为已读取,依靠TTL自动清理过期数据 */ async queryTaskResult(taskId: string): Promise { try { + // 检查缓存 + const cached = this.resultCache.get(taskId); + if (cached && Date.now() - cached.timestamp < this.CACHE_TTL) { + logger.info(`Task result retrieved from cache: ${taskId}`); + return cached.result; + } + // 确保 NeDB 数据库初始化 await NeDBManager.initialize(); diff --git a/src/lib/services/TaskPollingService.ts b/src/lib/services/TaskPollingService.ts index f2269bf..0d361d7 100644 --- a/src/lib/services/TaskPollingService.ts +++ b/src/lib/services/TaskPollingService.ts @@ -63,9 +63,9 @@ export class TaskPollingService { await NeDBManager.initialize(); taskLog('NeDB database initialized for task polling service'); - const pollIntervalMs = parseInt(process.env.TASK_POLL_INTERVAL || '5') * 1000; + const pollIntervalMs = parseInt(process.env.TASK_POLL_INTERVAL || '10') * 1000; - // 每5秒轮询一次(与心跳服务的60秒区分开) + // 每10秒轮询一次(优化性能,减少频繁查询) this.pollInterval = setInterval(async () => { await this.processTasks(); }, pollIntervalMs); @@ -113,9 +113,9 @@ export class TaskPollingService { // 3. 检查和处理超时任务 await this.checkTimeoutTasks(currentTime); - // 4. 定期清理(每720次轮询,约1小时) + // 4. 定期清理(每360次轮询,约1小时,基于10秒间隔) this.cleanupCounter++; - if (this.cleanupCounter >= 720) { + if (this.cleanupCounter >= 360) { await this.performCleanup(); this.cleanupCounter = 0; } @@ -223,7 +223,7 @@ export class TaskPollingService { try { // 检查是否需要重试(避免过于频繁的重试) const timeSinceLastUpdate = currentTime - task.updated_at; - const minRetryInterval = 30; // 最少等待30秒再重试 + const minRetryInterval = 60; // 最少等待60秒再重试,减少频繁重试 if (timeSinceLastUpdate < minRetryInterval) { return; // 还未到重试时间 @@ -612,7 +612,7 @@ export class TaskPollingService { const tosUrl = await TOSService.uploadFromUrl( url, `jimeng_free/${folder}/${task_id}/${fileName}`, - { maxRetries: 3 } // TOS客户端内部重试3次 + { maxRetries: 5, timeout: 120000 } // TOS客户端内部重试5次,超时2分钟 ); tosUrls.push(tosUrl); diff --git a/src/lib/tos/tos-client.ts b/src/lib/tos/tos-client.ts index 65ec603..a1282f5 100644 --- a/src/lib/tos/tos-client.ts +++ b/src/lib/tos/tos-client.ts @@ -49,9 +49,9 @@ export class TOSClientWrapper { endpoint: selfDomain, // 使用自定义域名作为 endpoint region, isCustomDomain: true, // 启用自定义域名 - connectionTimeout: 30000, - requestTimeout: 60000, - maxRetryCount: 3 + connectionTimeout: 60000, // 增加连接超时到60秒 + requestTimeout: 180000, // 增加请求超时到3分钟 + maxRetryCount: 5 // 增加重试次数到5次 }); // 禁用 SSL 警告(如果需要) @@ -196,7 +196,7 @@ export class TOSClientWrapper { objectKey: string, options: UploadOptions & { timeout?: number; maxRetries?: number } = {} ): Promise { - const { headers = {}, timeout = 30000, returnUrl = true, maxRetries = 3 } = options; + const { headers = {}, timeout = 120000, returnUrl = true, maxRetries = 5 } = options; if (!url.startsWith('http://') && !url.startsWith('https://')) { throw new Error('URL必须以http://或https://开头'); @@ -240,7 +240,7 @@ export class TOSClientWrapper { } // 等待一段时间后重试(指数退避) - const delay = Math.min(1000 * Math.pow(2, attempt - 1), 10000); // 最大10秒 + const delay = Math.min(2000 * Math.pow(2, attempt - 1), 30000); // 最大30秒 await new Promise(resolve => setTimeout(resolve, delay)); } }