136 lines
6.4 KiB
Java
136 lines
6.4 KiB
Java
package com.nanri.aiimage.config;
|
||
|
||
import lombok.Data;
|
||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||
|
||
import java.util.ArrayList;
|
||
import java.util.List;
|
||
|
||
@Data
|
||
@ConfigurationProperties(prefix = "aiimage.similar-asin")
|
||
public class SimilarAsinProperties {
|
||
private String cozeBaseUrl = "https://api.coze.cn";
|
||
private String cozeWorkflowPath = "/v1/workflow/run";
|
||
private String cozeWorkflowHistoryPath = "/v1/workflows/{workflow_id}/run_histories/{execute_id}";
|
||
private String cozeWorkflowId = "7635328462404583478";
|
||
private String cozeToken = "";
|
||
private List<CozeCredential> cozeCredentials = new ArrayList<>();
|
||
private int cozeCredentialStripeSize = 0;
|
||
/**
|
||
* P0-1:单次提交 Coze 工作流的 row 数量。
|
||
* 历史值 10,在含 puzzle 多图行的场景下频繁触发 720712008
|
||
* "node executed out of limit: 1000"。降到 3 以避免节点上限被打爆。
|
||
* 出现持续 720712008 时还会被 P1-1 滑窗自适应再降到 1。
|
||
* 不影响 AppearancePatentProperties 的同名值。
|
||
*/
|
||
private int cozeBatchSize = 3;
|
||
/**
|
||
* img_switch=false 时单次提交 Coze 的 row 数。
|
||
* 不走图片检测时工作流压力小,恢复到 10 行一批以提高吞吐;开启图片检测时仍使用 cozeBatchSize。
|
||
*/
|
||
private int cozeTextOnlyBatchSize = 10;
|
||
private int cozeConnectTimeoutMillis = 10000;
|
||
private int cozeReadTimeoutMillis = 60000;
|
||
private int cozePollIntervalMillis = 30000;
|
||
private int cozePollTimeoutMillis = 1800000;
|
||
private int staleTimeoutMinutes = 30;
|
||
private String staleFinalizeCron = "0 */2 * * * *";
|
||
|
||
/**
|
||
* 同一 credential 两次提交之间的最小间隔(毫秒)。
|
||
* 历史值硬编码 30000(持锁 sleep),导致单凭证仅 2 batch/分钟。
|
||
* 几千行任务场景下成为提交吞吐瓶颈,下调到 5000ms 并改为锁外冷却。
|
||
* 出现 Coze 限流加重时可通过 AIIMAGE_SIMILAR_ASIN_COZE_SUBMIT_MIN_INTERVAL_MILLIS 调高。
|
||
*/
|
||
private long cozeSubmitMinIntervalMillis = 5000L;
|
||
|
||
/**
|
||
* 末尾零头 batch 的强制 flush 阈值(分钟):当不足 cozeBatchSize 的零头 row
|
||
* 长时间挂着(Python 慢回传)时触发提交。
|
||
* 任务级实测:345 行 / 4h 总耗时中,约 2-3 小时是 batch 永远凑不满 batchSize 在等下一波回传,
|
||
* 把阈值从 15 调到 1:最多 60s 后 1-2 行也强制提交,让 Coze 提交侧持续进票,
|
||
* 总耗时降到与 Python 回传节奏接近。配合 cozeBatchSize=3、cozeSubmitMinIntervalMillis=5000,
|
||
* 实际不会触发 Coze 限流。出现限流加重再调回 5/10。
|
||
*/
|
||
private int cozeFlushPendingMinutes = 1;
|
||
|
||
/**
|
||
* 同 batch retry + split retry 共享的最大重试次数。原硬编码 5。
|
||
*/
|
||
private int cozeSubmitMaxRetryCount = 5;
|
||
|
||
/**
|
||
* 图片嵌入下载线程池大小。原 SimilarAsinImageEmbedder.DOWNLOAD_POOL_SIZE = 8。
|
||
* P2-10:1000+ 行 ×3 列图片场景下,pool=16 仍是 assemble 阶段瓶颈(实测下载 244s/918s),
|
||
* 提到 32 配合 retry=2、global deadline 显著拉低尾延迟;
|
||
* 受 2GB 堆约束,单图缩略图维持 300KB 以内,整体内存峰值 ≈ 32 * 300KB ≈ 10MB。
|
||
*/
|
||
private int imageDownloadPoolSize = 32;
|
||
|
||
/**
|
||
* 单张图片下载超时(秒)。
|
||
* P2-10:放宽到 8 + retry=1 在快源(aiproxy/m.media-amazon)下没问题,
|
||
* 但慢源(cbu01.alicdn)会一直挂 8s 才进入 retry,整体串行时间放大。
|
||
* 调到 5s + retry=2,让慢源更早重试新连接,单图最坏耗时 ≈ 5s * (1+2) = 15s。
|
||
*/
|
||
private int imageDownloadTimeoutSeconds = 5;
|
||
|
||
/**
|
||
* assemble 阶段 taskImageCache 的字节上限。
|
||
* 默认 256MB:5000 行 × 3 列 × 平均 100KB = 1.5GB 远超 2GB 堆,
|
||
* 用 BoundedImageCache 按字节累计 LRU 淘汰避免爆堆。
|
||
* 由于 embed() 写完即 remove(),活跃图片字节通常 ≤ 100MB,仅在极端 prefetch 领先场景才会触发淘汰。
|
||
* 出现淘汰过频影响命中率时可上调到 512MB;2GB 堆约束下不建议超过 768MB。
|
||
*/
|
||
private long imageCacheMaxBytes = 256L * 1024L * 1024L;
|
||
|
||
/**
|
||
* 是否在 Coze 请求 parameters 中附带 api_key 字段。
|
||
* 默认 true:线上 Coze 工作流将该字段视为必填,缺失会得到 4000
|
||
* "Missing required parameters";前端传入的 api_key 必须透传到 coze。
|
||
* 仅在工作流明确不再需要 api_key 时,可通过环境变量
|
||
* AIIMAGE_SIMILAR_ASIN_COZE_INCLUDE_LEGACY_API_KEY=false 关闭。
|
||
*/
|
||
private boolean cozeIncludeLegacyApiKey = true;
|
||
|
||
/**
|
||
* 是否使用旧的 item 字段顺序 {asin, sku, url, target_urls, title}。
|
||
* 默认 false:当前实现使用 {asin, url, target_urls, title, sku}。
|
||
* 出现兼容问题时可通过 AIIMAGE_SIMILAR_ASIN_COZE_USE_LEGACY_ITEM_ORDER=true
|
||
* 切回旧顺序进行回归对比。
|
||
*/
|
||
private boolean cozeUseLegacyItemFieldOrder = false;
|
||
|
||
/**
|
||
* 是否启用 P0-3 merge 增量缓冲:每个 batch DONE 时仅缓冲 cozeRows,
|
||
* 不立即合并到 chunk;finalize 前一次性按 chunkScopeHash 分组合并,
|
||
* 把 OSS chunk 读写从 1000+ 次降到 chunk 数量级。
|
||
* 仅作用于"正常 poll DONE"路径;失败 batch / 单 batch 任务 / 其他
|
||
* 11 个 mergeCozeRowsIntoChunk 调用点保留原立即 merge 行为。
|
||
* 出现问题时可通过 AIIMAGE_SIMILAR_ASIN_COZE_RESULT_BUFFER_ENABLED=false
|
||
* 一键回滚到老路径。
|
||
*/
|
||
private boolean cozeResultBufferEnabled = true;
|
||
|
||
/**
|
||
* P0-4:单 credential 抢 Coze 提交锁的最长等待时间(毫秒)。
|
||
* 原硬编码 1000ms,在高并发 split retry 时大量抛 "Coze submit throttle lock timeout"
|
||
* 并把整批行 markFailed。应与 cozeSubmitMinIntervalMillis(5000ms)保持 1.5-2 倍关系,
|
||
* 默认 10000ms 给抢锁更多时间。
|
||
*/
|
||
private long cozeSubmitLockWaitMillis = 10000L;
|
||
|
||
/**
|
||
* P0-4:抢 Coze 提交锁失败后下次重试间隔(毫秒)。
|
||
* 原硬编码 500ms,会在指数退避算法中作为基础值(500/1000/2000/4000ms 上限 4000)。
|
||
*/
|
||
private long cozeSubmitLockRetryDelayMillis = 500L;
|
||
|
||
@Data
|
||
public static class CozeCredential {
|
||
private String name;
|
||
private String workflowId;
|
||
private String token;
|
||
}
|
||
}
|