MST
星途 面试题库

面试题:JavaScript 在 Node HTTP 服务器性能优化之资源缓存策略

在基于 JavaScript 的 Node HTTP 服务器应用里,针对静态资源和动态响应数据,分别阐述至少两种有效的缓存策略及其在代码层面如何实现。
15.8万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

静态资源缓存策略及代码实现

  1. HTTP 缓存头(Expires 和 Cache - Control)
    • 策略:通过设置 Expires 头指定资源过期时间,或使用 Cache - Control 头更灵活地控制缓存行为,如 max - age 设置缓存时长。
    • 代码实现(Node.js)
const http = require('http');
const fs = require('fs');
const path = require('path');

const server = http.createServer((req, res) => {
    const filePath = path.join(__dirname, 'public', req.url);
    fs.readFile(filePath, (err, data) => {
        if (err) {
            res.statusCode = 404;
            res.end('Not Found');
        } else {
            res.setHeader('Content - Type', 'text/html');
            // 设置缓存,1 小时后过期
            res.setHeader('Cache - Control','max - age = 3600');
            res.end(data);
        }
    });
});

const port = 3000;
server.listen(port, () => {
    console.log(`Server running on port ${port}`);
});
  1. ETag 缓存
    • 策略:为资源生成唯一标识(ETag),客户端请求时带上 If - None - Match 头,服务器对比 ETag,若一致则返回 304 Not Modified,客户端使用本地缓存。
    • 代码实现(Node.js)
const http = require('http');
const fs = require('fs');
const path = require('path');
const crypto = require('crypto');

const server = http.createServer((req, res) => {
    const filePath = path.join(__dirname, 'public', req.url);
    const fileStat = fs.statSync(filePath);
    const etag = crypto.createHash('md5').update(fileStat.mtime + fileStat.size).digest('hex');
    if (req.headers['if - none - match'] === etag) {
        res.statusCode = 304;
        res.end();
    } else {
        fs.readFile(filePath, (err, data) => {
            if (err) {
                res.statusCode = 404;
                res.end('Not Found');
            } else {
                res.setHeader('Content - Type', 'text/html');
                res.setHeader('ETag', etag);
                res.end(data);
            }
        });
    }
});

const port = 3000;
server.listen(port, () => {
    console.log(`Server running on port ${port}`);
});

动态响应数据缓存策略及代码实现

  1. 内存缓存(简单对象缓存)
    • 策略:在服务器内存中使用对象存储动态响应数据,每次请求时先检查缓存中是否存在对应数据。
    • 代码实现(Node.js)
const http = require('http');
const cache = {};

const server = http.createServer((req, res) => {
    const cacheKey = req.url;
    if (cache[cacheKey]) {
        res.end(cache[cacheKey]);
    } else {
        // 模拟动态数据生成
        const dynamicData = 'Dynamic response data';
        cache[cacheKey] = dynamicData;
        res.end(dynamicData);
    }
});

const port = 3000;
server.listen(port, () => {
    console.log(`Server running on port ${port}`);
});
  1. 分布式缓存(使用 Redis)
    • 策略:使用 Redis 作为分布式缓存,多台服务器可以共享缓存数据。将动态响应数据存入 Redis,请求时从 Redis 获取。
    • 代码实现(Node.js,使用 ioredis 库)
const http = require('http');
const Redis = require('ioredis');
const redis = new Redis();

const server = http.createServer(async (req, res) => {
    const cacheKey = req.url;
    const cachedData = await redis.get(cacheKey);
    if (cachedData) {
        res.end(cachedData);
    } else {
        // 模拟动态数据生成
        const dynamicData = 'Dynamic response data';
        await redis.set(cacheKey, dynamicData);
        res.end(dynamicData);
    }
});

const port = 3000;
server.listen(port, () => {
    console.log(`Server running on port ${port}`);
});