设计思路
- 技术与模块:
- http模块:Node.js内置的
http
模块用于处理HTTP请求。它可以监听特定端口,接收并处理所有的HTTP请求。
- 中间件机制:借鉴Express等框架的中间件思想,在请求处理流程中插入拦截逻辑。虽然不一定要使用Express框架本身,但可以自行实现类似的中间件链式调用机制。
- 拦截与修改请求:
- 在HTTP请求处理函数中,首先检查请求头
headers
对象,判断是否存在X - Special - Request: true
标识。
- 如果存在,则对请求进行拦截。可以创建一个新的请求对象,将原请求的相关属性(如请求方法、请求头、请求体等)复制到新请求对象中,并进行必要的修改。
- 保证顺序性:
- 使用队列(如
async/await
结合数组模拟队列)来处理这些特定请求。将拦截到的请求放入队列中,依次处理队列中的请求,确保按顺序处理。
- 性能优化:
- 缓存:对于一些不变的配置或数据,使用缓存机制。例如,如果修改请求涉及到从数据库读取一些固定的数据,可以先将这些数据缓存起来,减少数据库查询次数。
- 异步处理:对于一些可能耗时的操作,如数据库查询或外部API调用,使用异步操作(如
async/await
或Promise),避免阻塞事件循环。
- 错误处理:
- 请求处理错误:在处理请求过程中,如果发生错误(如请求格式错误、数据库查询失败等),捕获错误并返回合适的HTTP错误状态码和错误信息给客户端。
- 队列处理错误:在队列处理过程中,如果某个请求处理失败,记录错误日志,同时继续处理队列中的下一个请求,避免因为一个请求失败而导致整个队列阻塞。
核心代码框架
const http = require('http');
const { promisify } = require('util');
const queue = [];
// 模拟一个可能耗时的异步操作
async function asyncOperation() {
// 这里可以是数据库查询等异步操作
await promisify(setTimeout)(1000);
return '操作结果';
}
const server = http.createServer(async (req, res) => {
if (req.headers['x - special - request'] === 'true') {
// 拦截请求
queue.push(req);
let processedReq;
try {
// 从队列中取出请求并处理
processedReq = queue.shift();
// 模拟对请求的修改
const result = await asyncOperation();
// 设置响应头和响应体
res.writeHead(200, { 'Content - Type': 'application/json' });
res.end(JSON.stringify({ message: '请求已处理', result }));
} catch (error) {
// 处理错误
res.writeHead(500, { 'Content - Type': 'application/json' });
res.end(JSON.stringify({ error: '请求处理失败' }));
// 如果当前请求处理失败,将其放回队列(可根据实际情况调整)
if (processedReq) {
queue.unshift(processedReq);
}
}
} else {
// 非特定请求直接处理
res.writeHead(200, { 'Content - Type': 'text/plain' });
res.end('普通请求已处理');
}
});
const port = 3000;
server.listen(port, () => {
console.log(`服务器在端口 ${port} 上运行`);
});