perf(aiot): 截图优化 — DB兜底 + 缓存TTL增到30分钟

问题:Redis缓存5分钟过期后,每次都重新触发Edge截图(15秒)

优化:
- Redis缓存TTL从5分钟增到30分钟(COS presigned URL有效1小时)
- Redis未命中时先查DB的cos_key,用CosUtil生成新presigned URL
- 只有DB也没有记录(首次截图)才触发Edge

效果:
- 首次截图:仍需触发Edge(不可避免)
- 后续访问:30分钟内走Redis缓存(毫秒级)
- 30分钟后:走DB → COS presign(秒级,无需Edge)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-04 11:10:26 +08:00
parent 90e9c1c896
commit f0466e84d4

View File

@@ -33,8 +33,8 @@ public class AiScreenshotServiceImpl implements IAiScreenshotService {
private static final String SNAP_CACHE_KEY_PREFIX = "snap:cache:"; private static final String SNAP_CACHE_KEY_PREFIX = "snap:cache:";
private static final String SNAP_RESULT_KEY_PREFIX = "snap:result:"; private static final String SNAP_RESULT_KEY_PREFIX = "snap:result:";
/** 缓存 TTL */ /** 缓存 TTL— 与 COS presigned URL 有效期(1小时)匹配,设为 30 分钟 */
private static final long SNAP_CACHE_TTL = 300; private static final long SNAP_CACHE_TTL = 1800;
/** 最大等待时间(秒) */ /** 最大等待时间(秒) */
private static final long MAX_WAIT_SECONDS = 15; private static final long MAX_WAIT_SECONDS = 15;
/** 降级 Redis 结果 TTL */ /** 降级 Redis 结果 TTL */
@@ -80,6 +80,21 @@ public class AiScreenshotServiceImpl implements IAiScreenshotService {
log.warn("[AI截图] 缓存解析失败: {}", e.getMessage()); log.warn("[AI截图] 缓存解析失败: {}", e.getMessage());
} }
} }
// 1.5 Redis 缓存未命中 → 从 DB 读取持久化的 cos_key生成新 presigned URL
// 这样 Redis 过期后不需要重新触发 Edge 截图
String cosKey = snapshotMapper.getCosKey(cameraCode);
if (cosKey != null && cosUtil.isAvailable()) {
String presignedUrl = cosUtil.generatePresignedUrl(cosKey);
if (presignedUrl != null) {
writeCache(cameraCode, presignedUrl);
result.put("status", "ok");
result.put("url", presignedUrl);
result.put("cached", true);
log.info("[AI截图] DB兜底命中: cameraCode={}, cosKey={}", cameraCode, cosKey);
return result;
}
}
} }
// 2. 生成 request_id 和 COS 路径 // 2. 生成 request_id 和 COS 路径