huangzd1997
76d9558851
progress 32
2026-08-29 20:11:20 +08:00
huangzd1997
2cd5e07248
task-32: 将 task entity 本地缓存替换为有容量和过期回收的实现
2026-08-29 20:11:16 +08:00
huangzd1997
5f7457a07b
progress 31
2026-08-29 20:04:26 +08:00
huangzd1997
cb4e10c87f
task-31: 将任务快照改为轻量进度字段,避免每次写入完整结果 JSON
2026-08-29 20:04:22 +08:00
huangzd1997
76a51ac290
progress 30
2026-08-29 19:52:14 +08:00
huangzd1997
199345fd11
task-30: 为国家结果行建立稳定去重键,替换线性重复扫描
2026-08-29 19:52:08 +08:00
huangzd1997
6e3b43d591
progress 29
2026-08-29 19:36:34 +08:00
huangzd1997
ec28216984
task-29: 合并 scope 状态查询与更新,减少单 chunk 数据库往返
...
persistResultScope 复用接收前已加载的 scope,不再重复 selectOne ——
每个分片接收的 scope 查询从 2 次降为 1 次;空分片校验前移至任何
scope 查询之前,非法分片零数据库往返。任务级分布式锁保证预读 scope
在锁内不过期。
2026-08-29 19:36:30 +08:00
huangzd1997
24ea02f150
progress 28
2026-08-29 19:26:03 +08:00
huangzd1997
f1db31f813
task-28: 以 scope 计数器替代每个 chunk 的 COUNT(*) 完整统计
...
分片接收不再对 chunk 表执行 selectCount 全量统计:新插入分片按 scope 计数器 +1
并钳制到 chunk_total,重复提交(唯一键冲突)保持不变;分片行与 scope 计数器
作为一致性单元,状态写入失败时回滚本次插入的分片行与 payload,重试走全新插入,
避免计数器重复计数或永久欠计。任务级分布式锁串行化同一任务的接收,读改写在锁内完成。
2026-08-29 19:25:59 +08:00
huangzd1997
7f49ef596e
progress 27
2026-08-29 19:11:17 +08:00
huangzd1997
23eddde770
task-27: chunk 接收改为原子插入/幂等 upsert,去掉先查后插
...
persistResultChunk 去除提交前的 findResultChunk 预查,直接 store payload + insert,
唯一索引 uk_task_scope_chunk 兜底幂等:重复提交命中 DuplicateKeyException 后
重查 winner 校验并清理本次重存 payload;空分片(无可处理数据)在落库前拒绝,
不创建 RustFS payload 与分片行。
2026-08-29 19:11:10 +08:00
huangzd1997
0092092dbd
progress: task-26 done (completed=26)
2026-08-29 18:55:05 +08:00
huangzd1997
8ea4d2f502
task-26: 模板 workbook 大行数下的样式、图片和工作表兼容测试
...
writeWorkbook(模板路径)改为返回实际写入行数,与 streaming 路径一致;
新增 1000/5000 行规模兼容测试:模板表头样式保留、同 URL 图片按 pictureIndex 去重复用、
5 工作表顺序名称保持模板语义、失败行兜底 URL 文本不中断整表。
全量测试 556 通过。
2026-08-29 18:55:01 +08:00
huangzd1997
6594e1f5d7
progress: task-25 done (completed=25)
2026-08-29 18:46:44 +08:00
huangzd1997
4e4af7911a
task-25: 店铺结果 workbook 的 SXSSF 流式写入路径
...
评估结论:SXSSF 无法访问/删除模板行,与现有模板重写流程不兼容,
故模板路径保留 XSSFWorkbook,另提供 writeWorkbookStreaming —— 空构造
SXSSFWorkbook + 自建 5 国工作表与表头,行数据按 rowAccessWindow spill 到磁盘,
写入后 dispose() 释放 spill 文件;图片嵌入复用现有链路,失败行兜底 URL 文本。
全量测试 548 通过。
2026-08-29 18:46:40 +08:00
huangzd1997
f816fed4f5
progress: task-24 done (completed=24)
2026-08-29 18:38:41 +08:00
huangzd1997
7eccbc016a
task-24: 店铺图片预取增加任务级数量、字节和超时上限
...
ShopDataCrawlPrefetchBudget 对预取 URL 施加三重预算:数量截断(去重后按序取前 N)、
字节估算门(urlCount×avgBytes 超预算拒绝)、超时钳制(200ms/URL 估算钳到任务上限);
Excel 组装在 prefetch 前应用预算,未预取 URL 由 embed 兜底直接下载。
全量测试 540 通过。
2026-08-29 18:38:37 +08:00
huangzd1997
a9cbd18246
progress: task-23 done (completed=23)
2026-08-29 18:34:05 +08:00
huangzd1997
70d724382d
task-23: 图片嵌入成功后立即释放外部缩略图字节副本
...
BoundedImageCache.release(url) 移除条目并扣减字节计数,byte[] 可被 GC 回收;
embedImage 在 addPicture 成功后立即释放,同一 URL 后续行复用 pictureIndex 不重复嵌入。
全量测试 532 通过。
2026-08-29 18:34:02 +08:00
huangzd1997
4a11fd612e
progress: task-22 done (completed=22)
2026-08-29 18:29:29 +08:00
huangzd1997
6d488515ca
task-22: 店铺 Excel 图片缓存替换为有界字节缓存
...
BoundedImageCache(字节预算+条目上限,FIFO 淘汰,超预算单图拒绝)替换
ShopDataCrawlExcelAssemblyService 中的无界 ConcurrentHashMap;单图超预算时
embed 走原有直接下载兜底。全量测试 524 通过。
2026-08-29 18:29:25 +08:00
huangzd1997
064e13c132
progress: task-21 done (completed=21)
2026-08-29 18:24:14 +08:00
huangzd1997
81da7a182e
task-21: 建立店铺抓取性能基线夹具(1k/5k 行、多国家、图片成功/失败)
...
ShopDataCrawlPerfFixture 提供单店铺多国家抓取结果的确定性生成器:
- generateItems:1k/5k 行、1-5 国家、图片成功/失败(前 N 行无缩略图)场景;
- samplePayload:行数/chunk 数/payload 字节/图片成功与失败行数采样。
全量测试 516 通过。
2026-08-29 18:24:10 +08:00
huangzd1997
3d5fd42bfa
progress: task-20 done (completed=20)
2026-08-29 18:18:37 +08:00
huangzd1997
29b6353d7e
task-20: Similar ASIN 端到端压测、GC 分析与结果文件兼容回归
...
SimilarAsinPerfFixture 新增三个功能点:
- endToEndBenchmark:生成→分 chunk→序列化,记录行数/chunk 数/payload 字节/耗时/吞吐/峰值堆;
- gcStressAnalysis:多轮生成/序列化/释放循环,采样 GC 计数差与堆峰值;
- compatRoundTrip:payload 序列化往返恢复全量行并校验字段稳定(结果文件兼容回归)。
全量测试 508 通过。
2026-08-29 18:18:24 +08:00
huangzd1997
9b5873bb84
progress: task-19 done (completed=19)
2026-08-29 18:11:28 +08:00
huangzd1997
77ae8b2823
task-19: Coze 请求/响应与 Python 回传日志改采样、截断、DEBUG
...
- 新增 SimilarAsinLogSupport 纯函数:truncate(2000 前缀+长度后缀,代理对安全)
与 shouldLog(每 N 次采样,计数 0 恒采样)
- Coze 请求 body 与 submit 响应正文日志降 DEBUG + 截断;
history 轮询响应降 DEBUG + 每 20 次记一次完整正文,其余只记状态
- Python 回传逐行日志降 DEBUG + 每 20 行采样一行,大任务日志量降到 5%
2026-08-29 18:11:24 +08:00
huangzd1997
07e99a5fa8
progress: task-18 done (completed=18)
2026-08-29 18:02:54 +08:00
huangzd1997
92858acb4d
task-18: 统一图片 spool 生命周期,超时/取消/异常路径删除临时文件
...
- ImageSpool 增加 closed 状态:close 幂等、close 后 put 拒绝且消息可识别,
杜绝关闭后再写入导致目录删除失败
- 长预算 prefetchToDisk 任务体补 put 前中断检查:deadline/中断取消后不再
产生新临时文件,close 可完整删除目录(与 best-effort 路径对齐)
- 长预算路径并入测试 hook 探测,与短预算路径行为一致,生命周期可测
2026-08-29 18:02:50 +08:00
huangzd1997
e1217c9c85
progress: task-17 done (completed=17)
2026-08-29 17:55:06 +08:00
huangzd1997
795dd1084c
task-17: 解码采样推广全格式、子采样后像素上限、JPEG 质量估算搜索
...
- sourceSubsampling 通用化:PNG 等非 JPEG 格式也按源长边取 2 的幂子采样,
reader 忽略采样参数时记录日志并按全量解码像素校验
- 新增 MAX_DECODED_PIXELS(2400^2) 子采样后解码像素上限,源像素超限先拒绝,
子采样仍超限再升采样因子,解码像素始终受控,36MP 源不再全量解码
- 质量搜索由固定阶梯 {0.75,0.65,0.55} 改为估算(字节比例钳制 [0.45,0.75]),
最坏编码 9 次降到 6 次,典型 1-2 次即命中,降低 CPU 峰值
2026-08-29 17:55:00 +08:00
huangzd1997
423666ef99
progress: task-16 done (completed=16)
2026-08-29 17:37:25 +08:00
huangzd1997
0e3dbe450f
task-16: 图片预取改短预算 best-effort,超时取消在途并回退 URL
...
prefetchToDiskBestEffort 在 budgetSeconds 内尽力预取,预算耗尽即取消
在途任务并返回未预取数量;缺图单元格由既有 fallback 直接写 URL。
put 前检查中断标志,避免取消后写盘与 spool close 竞态产生残留文件。
预算通过 aiimage.similar-asin.image-prefetch-budget-seconds 配置(默认 60s),
长预算后台预热路径 prefetchToDisk 行为不变。
2026-08-29 17:37:11 +08:00
huangzd1997
f517b7585f
progress: task-15 done (completed=15, rounds=15)
2026-08-29 17:24:31 +08:00
huangzd1997
dc69b002db
task-15: async batched last_used_at touch refresh
2026-08-29 17:24:25 +08:00
huangzd1997
fb10077557
progress: task-14 done (completed=14, rounds=14)
2026-08-29 17:16:47 +08:00
huangzd1997
d1ea8feb6f
task-14: batch read image db cache and touch only actual hits
2026-08-29 17:16:40 +08:00
huangzd1997
4030897d49
progress: task-13 done (completed=13, rounds=13)
2026-08-29 17:05:59 +08:00
huangzd1997
e201b13301
task-13: cap chunk merge row count and payload bytes with orphan fallback
2026-08-29 17:05:49 +08:00
huangzd1997
cbe0ec8bb2
task-12: mark done in progress
2026-08-29 16:46:38 +08:00
huangzd1997
4d91146256
task-12: extend coze result buffering beyond poll path
...
- bufferCozeRowsOrMerge: unified DONE result persist entry point; buffers to
transient storage when toggle on, falls back to immediate chunk merge on
failure (result never lost), no-op on empty input
- submit/retry synchronous immediate DONE results now buffer too (previously
always merged immediately); submit path persists a DONE scope state row to
carry the buffer pointer (persistImmediateCozeDoneState)
- poll path drops the batchTotal>1 gate: single-batch tasks also buffer
- CozeCandidate/CozeBatchContext records package-private for test access
2026-08-29 16:46:29 +08:00
huangzd1997
59ee3c8154
progress: task-11 done (completed=11, rounds=11)
2026-08-29 16:17:27 +08:00
huangzd1997
3d085c1605
task-11: Coze 结果合并前按稳定 rowKey HashSet 去重,消除 O(n²) 重复处理
2026-08-29 16:17:12 +08:00
huangzd1997
d64ba3a827
progress: task-10 done (completed=10, rounds=10)
2026-08-29 16:07:49 +08:00
huangzd1997
1ccf4f74ef
task-10: chunk 结果建立 rowKey 批量索引,消除跨 chunk 线性扫描
...
mergeCozeRowsIntoChunk 先 indexRowsByChunkKey 建立 rowKey→chunkKey
索引,assignCozeRowsToChunks 按 O(1) 查找分配行归属,保留原有
命中/fallback/orphan 语义与顺序稳定性,每 chunk 只读一次 payload。
2026-08-29 16:07:45 +08:00
huangzd1997
17a3292c78
progress: task-9 done (completed=9, rounds=9)
2026-08-29 15:52:57 +08:00
huangzd1997
99c0b7dd75
task-9: chunk 查询改为批量 keyset 分页,保持低内存读取
...
loadChunksKeyset 按 id 递增分批拉取(每批 pageSize),最后按
chunkIndex 升序合并,避免超大任务一次 selectList 全量载入 chunk
元数据。surefire fork 堆显式限制 1536m 防止与主 JVM 叠加挤爆内存。
2026-08-29 15:52:46 +08:00
huangzd1997
3b051bbafe
task-8: WorkbookFactory 输入解析改为受控读取,验证超大 Excel 失败提示
...
解析前用 ZipFile 中央目录探测 xlsx(zip) 条目数与解压总字节(不读压缩
内容),超过 maxWorkbookZipEntries(20000)/maxWorkbookUncompressedBytes
(512MB) 立即拒绝并给出可识别提示;非 zip/损坏文件跳过探测交给
WorkbookFactory 兜底转业务异常。0/负值配置回退默认。新增 8 个测试覆盖
正常路径、多文件、幂等、空输入、单行、解压超限、条目超限、损坏文件、
依赖失败恢复。
2026-08-29 15:11:53 +08:00
huangzd1997
68b7d9a4a4
task-7: 限制单文件大小、最大行数和最大字段长度,防止解析任务无界增长
...
新增 maxSourceFileBytes(50MB)/maxParseRows(50000)/maxFieldLength(2000)
三个配置项:文件超限在解析入口拒绝(异常消息可识别)、行数超限拒绝、
超长单元格字段截断。0/负值配置回退默认。新增 8 个测试覆盖正常路径、
多文件、幂等、空文件、单行、边界(恰好=上限通过、超限拒绝)、
非法输入(文件超限/字段截断)、依赖失败恢复。
2026-08-29 15:08:14 +08:00