From 554da10e99a6228019e05d411739b6d13fe8c4f9 Mon Sep 17 00:00:00 2001 From: hank9999 Date: Wed, 7 Jan 2026 14:01:51 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E4=BE=9B?= =?UTF-8?q?=E5=BA=94=E5=95=86=E7=BC=93=E5=AD=98=E5=BC=80=E5=85=B3=E9=85=8D?= =?UTF-8?q?=E7=BD=AE,=20=E9=BB=98=E8=AE=A4=E5=90=AF=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.example | 6 ++++++ src/lib/cache/provider-cache.ts | 7 +++++++ src/lib/config/env.schema.ts | 4 ++++ 3 files changed, 17 insertions(+) diff --git a/.env.example b/.env.example index e03069733..aca76ffb9 100644 --- a/.env.example +++ b/.env.example @@ -72,6 +72,12 @@ STORE_SESSION_MESSAGES=false # 是否存储请求 messages 到 Redis # - 启用:适用于网络稳定环境,连续网络错误也应触发熔断保护,避免持续请求不可达的供应商 ENABLE_CIRCUIT_BREAKER_ON_NETWORK_ERRORS=false +# 供应商缓存配置 +# 功能说明:控制是否启用供应商进程级缓存 +# - true (默认):启用缓存,30s TTL + Redis Pub/Sub 跨实例即时失效,提升供应商查询性能 +# - false:禁用缓存,每次请求直接查询数据库(适用于调试或单机低并发场景) +ENABLE_PROVIDER_CACHE=true + # Fetch 连接超时配置 # 功能说明:控制 TCP 连接建立超时时间(包括 DNS 查询、TCP 握手、TLS 握手) # - 默认值:30000 毫秒(30 秒) diff --git a/src/lib/cache/provider-cache.ts b/src/lib/cache/provider-cache.ts index c0415e6ba..ece8b58c1 100644 --- a/src/lib/cache/provider-cache.ts +++ b/src/lib/cache/provider-cache.ts @@ -11,6 +11,7 @@ import "server-only"; +import { getEnvConfig } from "@/lib/config"; import { logger } from "@/lib/logger"; import { publishCacheInvalidation, subscribeCacheInvalidation } from "@/lib/redis/pubsub"; import type { Provider } from "@/types/provider"; @@ -89,6 +90,12 @@ export async function publishProviderCacheInvalidation(): Promise { * @returns Provider 列表 */ export async function getCachedProviders(fetcher: () => Promise): Promise { + // 检查是否启用缓存(默认启用) + if (!getEnvConfig().ENABLE_PROVIDER_CACHE) { + logger.debug("[ProviderCache] Cache disabled, fetching from DB"); + return fetcher(); + } + // 确保订阅已初始化(异步,不阻塞) void ensureSubscription(); diff --git a/src/lib/config/env.schema.ts b/src/lib/config/env.schema.ts index ccaee2e33..fd9eaf74f 100644 --- a/src/lib/config/env.schema.ts +++ b/src/lib/config/env.schema.ts @@ -99,6 +99,10 @@ export const EnvSchema = z.object({ TZ: z.string().default("Asia/Shanghai"), ENABLE_MULTI_PROVIDER_TYPES: z.string().default("false").transform(booleanTransform), ENABLE_CIRCUIT_BREAKER_ON_NETWORK_ERRORS: z.string().default("false").transform(booleanTransform), + // 供应商缓存开关 + // - true (默认):启用进程级缓存,30s TTL,提升供应商查询性能 + // - false:禁用缓存,每次请求直接查询数据库 + ENABLE_PROVIDER_CACHE: z.string().default("true").transform(booleanTransform), MAX_RETRY_ATTEMPTS_DEFAULT: z.coerce .number() .min(1, "MAX_RETRY_ATTEMPTS_DEFAULT 不能小于 1") From 30af74892cbaf6cb4d0d68dd3cbfc29b89f47c05 Mon Sep 17 00:00:00 2001 From: hank9999 Date: Wed, 7 Jan 2026 14:26:21 +0800 Subject: [PATCH 2/2] =?UTF-8?q?refactor:=20=E4=BC=98=E5=8C=96=E7=BC=93?= =?UTF-8?q?=E5=AD=98=E5=BC=80=E5=85=B3=E8=AF=BB=E5=8F=96=E6=96=B9=E5=BC=8F?= =?UTF-8?q?,=20=E9=81=BF=E5=85=8D=E7=83=AD=E8=B7=AF=E5=BE=84=E5=87=BD?= =?UTF-8?q?=E6=95=B0=E4=B8=AD=E9=A2=91=E7=B9=81=E8=B0=83=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/lib/cache/provider-cache.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/lib/cache/provider-cache.ts b/src/lib/cache/provider-cache.ts index ece8b58c1..32b2efd81 100644 --- a/src/lib/cache/provider-cache.ts +++ b/src/lib/cache/provider-cache.ts @@ -16,6 +16,9 @@ import { logger } from "@/lib/logger"; import { publishCacheInvalidation, subscribeCacheInvalidation } from "@/lib/redis/pubsub"; import type { Provider } from "@/types/provider"; +// 模块级别读取配置,避免热路径函数中频繁调用 +const { ENABLE_PROVIDER_CACHE } = getEnvConfig(); + export const CHANNEL_PROVIDERS_UPDATED = "cch:cache:providers:updated"; const CACHE_TTL_MS = 30_000; // 30 seconds @@ -91,7 +94,7 @@ export async function publishProviderCacheInvalidation(): Promise { */ export async function getCachedProviders(fetcher: () => Promise): Promise { // 检查是否启用缓存(默认启用) - if (!getEnvConfig().ENABLE_PROVIDER_CACHE) { + if (!ENABLE_PROVIDER_CACHE) { logger.debug("[ProviderCache] Cache disabled, fetching from DB"); return fetcher(); }