Skip to content

Commit 8cd265b

Browse files
committed
fix(rate-limit): 兼容 Vercel Upstash 集成的多种 env 命名
Vercel 的 Upstash 集成在不同 prefix 设置下会生成不同命名: - 无 prefix → KV_REST_API_URL / _TOKEN - prefix=X → X_KV_REST_API_URL / _TOKEN (prefix 被前置而非替换) 手动从 Upstash 控制台复制则是 UPSTASH_REDIS_REST_URL / _TOKEN。 新增 firstEnv() helper 按优先级依次探查,读到谁用谁: 1. UPSTASH_REDIS_REST_URL (手动配) 2. UPSTASH_REDIS_REST_KV_REST_API_URL (Vercel + 自定义 prefix) 3. KV_REST_API_URL (Vercel + 无 prefix) .env.sample 同步说明三种命名。
1 parent 2f233c4 commit 8cd265b

2 files changed

Lines changed: 35 additions & 4 deletions

File tree

.env.sample

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,15 @@ ZHIPU_API_KEY=
3232

3333
# Upstash Redis(Serverless Redis over HTTP)—— 给 AI 接口做 per-IP rate limit
3434
# 免费模型 GLM-4.6V-Flash 并发极低(≈5),不限流单用户就能打爆。
35-
# 在 https://console.upstash.com/ 创建 Redis 数据库后复制 REST URL / Token,
36-
# 或者在 Vercel Project → Integrations → Upstash 一键绑定(env 会自动塞进来)。
35+
#
36+
# 获取方式(任选其一):
37+
# 1. 在 https://console.upstash.com/ 手动建 Redis 库,直接复制 REST URL / Token
38+
# 2. Vercel Project → Integrations → Upstash → 一键绑定(env 会自动注入项目)
39+
#
40+
# 代码会自动识别以下三种命名(按优先级):
41+
# a. UPSTASH_REDIS_REST_URL / _TOKEN (手动建推荐)
42+
# b. UPSTASH_REDIS_REST_KV_REST_API_URL / _TOKEN (Vercel 集成 + 自定义 prefix)
43+
# c. KV_REST_API_URL / _TOKEN (Vercel 集成 + 默认无 prefix)
3744
# 未配置时限流会自动降级为放行 + 一次 warn,不会阻塞接口。
3845
UPSTASH_REDIS_REST_URL=
3946
UPSTASH_REDIS_REST_TOKEN=

lib/rate-limit.ts

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,33 @@ let cachedDailyLimiter: Ratelimit | null = null;
2222
// 避免生产环境每请求刷爆 serverless 日志(Copilot CR #3)
2323
let hasWarnedMissingUpstash = false;
2424

25+
/**
26+
* 挑第一个非空 env var 返回;本地开发 + Vercel 不同集成版本的命名差异靠它兜住。
27+
*/
28+
function firstEnv(...names: string[]): string | undefined {
29+
for (const n of names) {
30+
const v = process.env[n];
31+
if (v && v.trim()) return v;
32+
}
33+
return undefined;
34+
}
35+
2536
function getRedis(): Redis | null {
26-
const url = process.env.UPSTASH_REDIS_REST_URL;
27-
const token = process.env.UPSTASH_REDIS_REST_TOKEN;
37+
// Upstash 的 env 名字在不同集成路径下会长得不一样:
38+
// - 手动从 Upstash 控制台复制 → UPSTASH_REDIS_REST_URL / _TOKEN
39+
// - Vercel 集成、无自定义 prefix → KV_REST_API_URL / KV_REST_API_TOKEN
40+
// - Vercel 集成、prefix=UPSTASH_... → UPSTASH_REDIS_REST_KV_REST_API_URL ...
41+
// 按上面优先级依次查找,读到谁用谁,免得跟集成命名斗智斗勇。
42+
const url = firstEnv(
43+
"UPSTASH_REDIS_REST_URL",
44+
"UPSTASH_REDIS_REST_KV_REST_API_URL",
45+
"KV_REST_API_URL",
46+
);
47+
const token = firstEnv(
48+
"UPSTASH_REDIS_REST_TOKEN",
49+
"UPSTASH_REDIS_REST_KV_REST_API_TOKEN",
50+
"KV_REST_API_TOKEN",
51+
);
2852
if (!url || !token) return null;
2953
return new Redis({ url, token });
3054
}

0 commit comments

Comments
 (0)