You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为Server Actions实现缓存:可行性及实现方法问询

为Server Actions实现缓存的几种方案

当然可以给Server Actions实现缓存,针对你的getProjects函数,这里有几种实用的方案:

1. 内存级缓存(适合单服务器/开发环境)

这种方案最简单,用内存存储缓存数据,适合单实例场景,缺点是服务器重启或多实例部署时缓存会失效:

"use server"

// 内存缓存容器,单实例内有效
const cacheStore = new Map();

export const getProjects = async () => {
  const cacheKey = "projects_list";
  const cachedEntry = cacheStore.get(cacheKey);

  // 检查缓存是否在1小时有效期内
  if (cachedEntry && Date.now() - cachedEntry.timestamp < 3600 * 1000) {
    return cachedEntry.data;
  }

  // 缓存失效,执行数据库查询
  const projects = await db(
    `
    SELECT p.id, p.project_name,
           (SELECT i.image_url 
            FROM images i 
            WHERE i.project_id = p.id 
            ORDER BY i.id DESC 
            LIMIT 1) AS latest_image
    FROM projects p
    `
  );

  // 更新缓存,记录时间戳
  cacheStore.set(cacheKey, {
    data: projects,
    timestamp: Date.now()
  });

  return projects;
};

2. 外部缓存系统(适合生产多实例环境)

用Redis这类分布式缓存系统,解决多实例缓存不一致的问题,生产环境首选:

"use server"
import Redis from 'ioredis';

// 初始化Redis客户端,从环境变量读取连接地址
const redisClient = new Redis(process.env.REDIS_URL);

export const getProjects = async () => {
  const cacheKey = "projects_list";
  const cachedData = await redisClient.get(cacheKey);

  if (cachedData) {
    // 解析缓存的JSON数据
    return JSON.parse(cachedData);
  }

  const projects = await db(
    `
    SELECT p.id, p.project_name,
           (SELECT i.image_url 
            FROM images i 
            WHERE i.project_id = p.id 
            ORDER BY i.id DESC 
            LIMIT 1) AS latest_image
    FROM projects p
    `
  );

  // 设置缓存1小时过期
  await redisClient.set(cacheKey, JSON.stringify(projects), 'EX', 3600);

  return projects;
};

3. Next.js专属:unstable_cache API(Next.js 13+)

如果你用的是Next.js,官方提供了unstable_cache可以直接给Server Actions添加缓存,无需自己管理存储:

"use server"
import { unstable_cache } from 'next/cache';

// 封装原始查询函数
const fetchProjects = async () => {
  return await db(
    `
    SELECT p.id, p.project_name,
           (SELECT i.image_url 
            FROM images i 
            WHERE i.project_id = p.id 
            ORDER BY i.id DESC 
            LIMIT 1) AS latest_image
    FROM projects p
    `
  );
};

// 用unstable_cache包装,设置1小时重新验证时间
export const getProjects = unstable_cache(
  fetchProjects,
  ['projects_list'], // 用于区分缓存的唯一标识数组
  { revalidate: 3600 } // 缓存有效期(秒)
);

注意:unstable_cache目前是不稳定API,后续版本可能有变更,使用时留意Next.js官方文档更新。

额外注意事项

  • 确保缓存键唯一,避免和其他业务的缓存数据冲突
  • 当项目数据更新时,需要主动清除对应缓存(比如调用redisClient.del(cacheKey)或Next.js的revalidateTag),避免返回旧数据
  • 内存缓存不要存储过大的数据,防止服务器内存溢出

内容的提问来源于stack exchange,提问作者Morgana Freeman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 04:03:11