node中缓存设置

强制缓存

强制缓存,只对引用的资源缓存

缺陷:无服务文件修改,可能还是走的缓存,不能即使获取最新文件

//30s
res.setHeader('Cache-Control', 'max-age=30');
//兼容低版本, 到什么时间结束
res.setHeader('Expires', new Date(Date.now() + 30 * 1000).toUTCString());

协商缓存

  • no-cache: 缓存,但是每次会请求服务器
  • no-store: 不缓存

缺点:

  • 可能文件没变化,时间变化了
  • 不够精准
  • 可能CDN放置到服务器上的时间不一致
//获取文件修改时间
const ctime = stats.ctime.toUTCString();
//获取请求携带的最后修改时间
const ifModifiedSince = req.headers['if-modified-since'];
//如果请求携带的修改时间跟服务器文件的修改时间一直,走缓存
if (ctime === ifModifiedSince) {
    res.statusCode = 304;
    res.end();
} else {
    //设置最后修改时间
    res.setHeader('Last-Modified', ctime);
    res.end();
}

指纹缓存(etag)

读文文件内容,产生 md5 戳,可以用 md5 戳校验,但是读取文件时间长,一般需要产生一个相对简单的etag

const crypto = require('crypto')

//获取请求携带的etag
const reqEtag = req.headers['if-none-match'];
//根据文件生产一个指纹
const etag = cryto.createHash('md5').update(fs.readFileSync(filePath)).digest('base64');
//如果请求携带的指纹跟服务器的指纹相同,走缓存
if (reqEtag === etag) {
    res.statusCode = 304;
    res.end()
} else {
    //设置etag
    res.setHeader('Etag', etag);
    res.setHeader('Content-Type', `${mime.getType(filePath)};charset=utf8`);
    fs.createReadStream(filePath).pipe(res);
}
### 缓存 Token 的最佳实践 在 Node.js 环境下,缓存 Token 是一种常见的需求,尤其是在涉及身份验证的应用程序中。以下是几种常用的缓存方法及其优缺点分析。 #### 使用内存存储(如 `Map` 或 `Object`) 对于简单的应用场景,可以直接使用 JavaScript 原生的数据结构来缓存 Token。这种方法适合小型项目或测试环境,因为它不需要额外依赖外部服务。 ```javascript const tokenCache = new Map(); function cacheToken(token, data) { const expirationTime = Date.now() + (data.expireIn * 1000); // 转换为毫秒 tokenCache.set(token, { ...data, expiresAt: expirationTime }); } function getTokenData(token) { const cachedData = tokenCache.get(token); if (!cachedData || cachedData.expiresAt < Date.now()) { tokenCache.delete(token); // 清理过期的 Token return null; } return cachedData; } ``` 这种方式的优点在于简单易用且性能高[^1],但由于数据仅存在于内存中,在服务器重启后会丢失所有缓存内容。 --- #### 使用 Redis 进行分布式缓存 Redis 是一个高性能的键值数据库,非常适合用来缓存 Token 数据。它支持持久化、TTL(时间至活)设置以及跨多台机器共享缓存的能力。 安装并连接 Redis: ```bash npm install redis ``` 代码示例: ```javascript const redis = require('redis'); const client = redis.createClient(); // 创建 Redis 客户端实例 client.on('error', (err) => console.error(`Redis Client Error: ${err}`)); // 存储 Token 到 Redis 并设置 TTL function cacheTokenToRedis(token, data) { const ttlInSeconds = data.expireIn; // 单位:秒 client.SETEX(token, ttlInSeconds, JSON.stringify(data)); } // 获取 Token 数据 function getTokenFromRedis(token, callback) { client.GET(token, (err, result) => { if (err) throw err; if (!result) return callback(null, null); // 如果没有找到对应的 Token,则返回 null try { const parsedResult = JSON.parse(result); callback(null, parsedResult); } catch (e) { callback(e, null); } }); } ``` 通过 Redis 实现缓存的优势在于其强大的扩展性和可靠性[^2],尤其适用于需要在多个节点之间共享状态的服务架构。 --- #### 结合 JWT 和缓存机制优化认证流程 当使用 JsonWebToken 模块生成和解析 Token 时,可以通过缓存进一步提升效率。例如,可以在首次成功验证 Token 后将其保存到缓存中,并在未来请求中优先查询缓存而不是重新计算签名。 ```javascript const jwt = require('jsonwebtoken'); async function verifyAndCacheToken(token) { let cachedData = await getTokenFromRedis(token); // 尝试从 Redis 中获取已缓存的 Token if (cachedData) { return Promise.resolve(cachedData); // 若存在则直接返回 } return new Promise((resolve, reject) => { jwt.verify(token, 'your-secret-key', async (err, decoded) => { if (err) return reject(err); // 验证成功后将 Token 缓存起来 await cacheTokenToRedis(token, decoded); resolve(decoded); }); }); } ``` 此方案不仅减少了重复计算的工作量,还增强了系统的响应速度[^3]。 --- ### 总结 - 对于单机部署的小型应用,可以选择基于内存的方式快速实现 Token 缓存功能。 - 当面对更复杂的场景或者分布式的系统设计时,推荐采用 Redis 来管理 Token 缓存。 - 在实际开发过程中,应综合考虑业务特点和技术栈特性选取最适合的技术手段。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值