fix(admin): upgrade ioredis cluster to 5.x RedisCluster API
Some checks are pending
CI / Rust Lint & Check (push) Waiting to run
CI / Rust Tests (push) Waiting to run
CI / Frontend Lint & Type Check (push) Waiting to run
CI / Frontend Build (push) Blocked by required conditions

- Replace deprecated Cluster with RedisCluster (ioredis 5.x breaking change)
- Extract username/password from cluster URLs for authentication
- Fix REDIS_CLUSTER_URLS to include all 3 master nodes with default user
This commit is contained in:
ZhenYi 2026-04-20 09:28:28 +08:00
parent a3fcbab5d8
commit 09d5a5877f
2 changed files with 15 additions and 15 deletions

View File

@ -71,8 +71,8 @@ admin:
env: env:
DATABASE_URL: "postgresql://gitdataai:gitdataai123@cnpg-cluster-rw.cnpg:5432/gitdataai?sslmode=disable" DATABASE_URL: "postgresql://gitdataai:gitdataai123@cnpg-cluster-rw.cnpg:5432/gitdataai?sslmode=disable"
REDIS_CLUSTER_URLS: "redis://:redis123@valkey-cluster.valkey-cluster.svc.cluster.local:6379" REDIS_CLUSTER_URLS: "redis://default:redis123@valkey-cluster-0.valkey-cluster.valkey-cluster.svc.cluster.local:6379,redis://default:redis123@valkey-cluster-1.valkey-cluster.valkey-cluster.svc.cluster.local:6379,redis://default:redis123@valkey-cluster-2.valkey-cluster.valkey-cluster.svc.cluster.local:6379"
REDIS_URL: "redis://:redis123@valkey-cluster.valkey-cluster.svc.cluster.local:6379" REDIS_URL: "redis://default:redis123@valkey-cluster.valkey-cluster.svc.cluster.local:6379"
ADMIN_SESSION_COOKIE_NAME: admin_session ADMIN_SESSION_COOKIE_NAME: admin_session
ADMIN_SESSION_TTL: 604800 ADMIN_SESSION_TTL: 604800
ADMIN_SUPER_USERNAME: admin ADMIN_SUPER_USERNAME: admin

View File

@ -3,7 +3,7 @@
* *
* admin:* * admin:*
*/ */
import Redis, { Cluster } from "ioredis"; import Redis, { RedisCluster } from "ioredis";
import { REDIS_URL, REDIS_CLUSTER_URLS } from "./env"; import { REDIS_URL, REDIS_CLUSTER_URLS } from "./env";
// Admin 专用的 Redis 前缀 // Admin 专用的 Redis 前缀
@ -11,7 +11,7 @@ const ADMIN_PREFIX = "admin:session:";
// 平台用户 Session 前缀(与 Rust 主应用一致) // 平台用户 Session 前缀(与 Rust 主应用一致)
const PLATFORM_SESSION_PREFIX = "session:user_uid:"; const PLATFORM_SESSION_PREFIX = "session:user_uid:";
let redis: Redis | Cluster | null = null; let redis: Redis | RedisCluster | null = null;
function createSingleClient(): Redis { function createSingleClient(): Redis {
return new Redis(REDIS_URL, { return new Redis(REDIS_URL, {
@ -23,7 +23,7 @@ function createSingleClient(): Redis {
}); });
} }
function createClusterClient(): Redis | Cluster { function createClusterClient(): Redis | RedisCluster {
if (REDIS_CLUSTER_URLS.length === 0) { if (REDIS_CLUSTER_URLS.length === 0) {
return createSingleClient(); return createSingleClient();
} }
@ -33,24 +33,24 @@ function createClusterClient(): Redis | Cluster {
return { host: u.hostname, port: parseInt(u.port || "6379", 10) }; return { host: u.hostname, port: parseInt(u.port || "6379", 10) };
}); });
// ioredis cluster 需要至少一个节点,会自动处理 MOVED 重定向 const firstUrl = new URL(REDIS_CLUSTER_URLS[0]);
const cluster = new Cluster(nodes, {
// ioredis 5.x: RedisCluster, redisOptions 展开到顶层, 无 clusterRetryStrategy
const cluster = new RedisCluster(nodes, {
lazyConnect: true, lazyConnect: true,
redisOptions: { maxRetriesPerRequest: 3,
maxRetriesPerRequest: 3, retryStrategy(times) {
retryStrategy(times) {
return Math.min(times * 100, 3000);
},
},
clusterRetryStrategy(times) {
return Math.min(times * 100, 3000); return Math.min(times * 100, 3000);
}, },
// 从第一个 URL 提取认证信息(所有节点共用相同密码)
username: firstUrl.username || undefined,
password: firstUrl.password || undefined,
}); });
return cluster as unknown as Redis; return cluster as unknown as Redis;
} }
export function getRedis(): Redis | Cluster { export function getRedis(): Redis | RedisCluster {
if (!redis) { if (!redis) {
redis = redis =
REDIS_CLUSTER_URLS.length > 1 ? createClusterClient() : createSingleClient(); REDIS_CLUSTER_URLS.length > 1 ? createClusterClient() : createSingleClient();