perf(全链路): 连接池/事务边界/轮询与 IO 效率收口

Java:
- LLM 180s 读超时不再被全局 call-timeout 静默截断成 90s(长思考请求被掐断→重试→付费网关二次计费)
- 代理 HttpClient 缓存改有界 LRU(jikip 每次提取新 IP,无界缓存持续泄漏 selector 线程与连接池)
- 12 个 service 的 Redis 任务锁移出 @Transactional(自旋最坏 10s 白占 DB 连接,池仅 30),远端对象删/传改 afterCommit
- 结果文件 Job 闸门拒绝时不再回退内联执行(改重新入队,避免把背压转嫁给 MQ 消费线程)
- imagevideo 每秒扫描加列投影、过期清理加 LIMIT;权限页整表查询改列投影(不再拉回密码哈希)
- 哈希改 HexFormat;补 5 处"不能改"的技术依据注释(批量插入会丢回填主键、流式丢模板与图片等)

前端:4 个工具页轮询改轻量端点(带 fallback);PriceTrack 快照节流写盘;候选店铺表分页;页面隐藏时停表

客户端:HTTP 连接池按出口复用(Session 仍每请求新建,保持无跨请求状态);品牌检测 WIPO 逐请求握手;
代理配置按 mtime 缓存;串行任务改专属池;异常降级为标签页重连;紫鸟启动改端口轮询;模板编译缓存;
日志上报连接与落盘收口;Flask 版本 API 改按请求复用连接
This commit is contained in:
2026-09-15 23:01:59 +08:00
parent d6f8368493
commit 228d481211
44 changed files with 1550 additions and 423 deletions
@@ -1,5 +1,7 @@
package com.nanri.aiimage.config;
import com.nanri.aiimage.common.util.BoundedLruCache;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.JdkClientHttpRequestFactory;
@@ -14,8 +16,6 @@ import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Task 77:外部 HTTP 客户端统一连接复用池。
@@ -24,6 +24,7 @@ import java.util.concurrent.ConcurrentHashMap;
* 每次请求都重新建连。各客户端按自身超时创建独立的
* JdkClientHttpRequestFactory(共享底层连接池),RestClient 单例懒加载。
*/
@Slf4j
public class HttpClientPool {
private static volatile HttpClient sharedHttpClient;
@@ -103,8 +104,12 @@ public class HttpClientPool {
public static ClientHttpRequestFactory requestFactory(int readTimeoutMillis, String proxyUrl) {
long safeReadTimeout = Math.max(1L, readTimeoutMillis);
long callTimeout = configuredCallTimeoutMillis;
if (callTimeout > 0L) {
safeReadTimeout = Math.min(safeReadTimeout, callTimeout);
if (callTimeout > 0L && safeReadTimeout > callTimeout) {
// 读超时以调用方显式值为准,不再被全局 call-timeout 截断:
// LLM 长思考配的是 180sllm-read-timeout-millis),曾被静默压到 90s
// 导致请求在 90s 被掐断 → 上层重试 → 付费网关二次计费(2026-09-15 修复)。
// 各调用方的超时已由各自的 HttpConfigResolver 钳制,此处不再二次收敛。
log.debug("读超时 {}ms 超过全局 call-timeout {}ms,按调用方显式值生效", safeReadTimeout, callTimeout);
}
JdkClientHttpRequestFactory factory =
new JdkClientHttpRequestFactory(httpClientFor(proxyUrl));
@@ -166,5 +171,6 @@ public class HttpClientPool {
private record ProxyEndpoint(String host, int port, String userInfo) {
}
private static final Map<ProxyEndpoint, HttpClient> PROXY_CLIENTS = new ConcurrentHashMap<>();
private static final BoundedLruCache<ProxyEndpoint, HttpClient> PROXY_CLIENTS =
new BoundedLruCache<>(BoundedLruCache.DEFAULT_MAX_SIZE);
}