在 Koa 中利用缓存优化性能,可以通过 内存缓存、HTTP 缓存、Redis 缓存、CDN 缓存 等多种方式实现。以下是具体方案和代码示例:
适用于 静态资源(CSS/JS/图片) 或 不常变动的 API 响应。
通过设置 Cache-Control和 ETag头,让浏览器或 CDN 缓存响应。
const Koa = require('koa');
const app = new Koa();
// 静态资源缓存(1小时)
app.use(async (ctx, next) => {
if (ctx.path.startsWith('/static')) {
ctx.set('Cache-Control', 'public, max-age=3600');
}
await next();
});
// API 缓存(10秒)
app.use(async (ctx, next) => {
if (ctx.path.startsWith('/api')) {
ctx.set('Cache-Control', 'public, max-age=10');
}
await next();
});
const etag = require('koa-etag');
const conditional = require('koa-conditional-get');
app.use(conditional()); // 支持 If-None-Match
app.use(etag()); // 自动生成 ETag
app.use(async (ctx) => {
ctx.body = { data: 'This can be cached!' };
});
浏览器首次请求:返回 200 OK+ ETag
后续请求:浏览器发送 If-None-Match,若未变化返回 304 Not Modified
适用于 短期高频访问但较少变动的数据(如配置、热门数据)。
使用 node-cache或 lru-cache实现内存缓存。
const NodeCache = require('node-cache');
const cache = new NodeCache({ stdTTL: 60 }); // 默认缓存60秒
app.use(async (ctx, next) => {
if (ctx.path === '/api/data') {
const cachedData = cache.get('data_key');
if (cachedData) {
ctx.body = { data: cachedData, source: 'cache' };
return;
}
// 模拟数据库查询
const freshData = await fetchDataFromDB();
cache.set('data_key', freshData);
ctx.body = { data: freshData, source: 'database' };
}
await next();
});
const LRU = require('lru-cache');
const cache = new LRU({ max: 500, maxAge: 1000 * 60 }); // 最多500条,缓存1分钟
app.use(async (ctx) => {
if (ctx.path === '/api/users') {
const cachedUsers = cache.get('users');
if (cachedUsers) {
ctx.body = { users: cachedUsers, source: 'cache' };
return;
}
const users = await fetchUsersFromDB();
cache.set('users', users);
ctx.body = { users, source: 'database' };
}
});
适用于 多实例部署 或 需要持久化的缓存(如用户会话、热点数据)。
const Redis = require('ioredis');
const redis = new Redis(); // 默认连接本地6379
app.use(async (ctx) => {
if (ctx.path === '/api/posts') {
const cachedPosts = await redis.get('posts');
if (cachedPosts) {
ctx.body = { posts: JSON.parse(cachedPosts), source: 'redis' };
return;
}
const posts = await fetchPostsFromDB();
await redis.set('posts', JSON.stringify(posts), 'EX', 60); // 缓存60秒
ctx.body = { posts, source: 'database' };
}
});
const koaRedisCache = require('koa-redis-cache');
app.use(koaRedisCache({
prefix: 'cache:', // Redis key 前缀
expire: 60, // 默认缓存60秒
passParam: 'skipCache', // 可跳过缓存的参数(如 ?skipCache=true)
}));
适用于 CSS/JS/图片等静态文件,减少服务器负载。
const static = require('koa-static');
app.use(static('public', {
maxAge: 86400 * 365, // 缓存1年
immutable: true, // 资源内容不变
}));
location /static/ {
expires 1y;
add_header Cache-Control "public, immutable";
}
koa怎么利用缓存提高性能?
发布时间:2025-9-14
分类:技术
标签: koa 客户评价 node