面试题答案
一键面试1. 异常处理机制设计
- 捕获全局异常
在Node.js中,可以使用
process.on('uncaughtException', (err) => {})
来捕获未被处理的异常。这对于确保即使出现未预料到的错误,程序也不会突然崩溃很有帮助。
process.on('uncaughtException', (err) => {
console.error('Uncaught Exception:', err.message);
console.error(err.stack);
// 可以在这里添加清理操作,如关闭数据库连接等
});
- HTTP请求异常处理
在HTTP服务器处理请求时,使用
try - catch
块来捕获可能发生的异常。例如:
const http = require('http');
const server = http.createServer((req, res) => {
try {
// 处理请求逻辑
if (Math.random() < 0.5) {
throw new Error('Simulated error');
}
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Success');
} catch (err) {
res.writeHead(500, { 'Content-Type': 'text/plain' });
res.end('Internal Server Error');
// 记录错误日志
console.error('HTTP Request Error:', err.message);
console.error(err.stack);
}
});
const port = 3000;
server.listen(port, () => {
console.log(`Server running on port ${port}`);
});
- 资源耗尽处理
使用
process.on('warning', (warning) => {})
来捕获资源相关的警告,如内存泄漏、文件描述符耗尽等。例如:
process.on('warning', (warning) => {
console.warn('Warning:', warning.name);
console.warn(warning.message);
console.warn(warning.stack);
});
2. 结合Cluster模块实现负载均衡与容错处理
- 负载均衡 Cluster模块允许Node.js应用程序在多个进程间共享服务器端口。主进程(也称为master进程)负责监听端口,并将新的连接分发给工作进程(worker进程)。示例代码如下:
const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
console.log(`Master ${process.pid} is running`);
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('exit', (worker, code, signal) => {
console.log(`worker ${worker.process.pid} died`);
cluster.fork();
});
} else {
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello World from worker ' + process.pid);
});
server.listen(3000, () => {
console.log(`Worker ${process.pid} started`);
});
}
在上述代码中,主进程创建了与CPU核心数量相同的工作进程,并在有工作进程退出时重新创建新的工作进程,以确保负载均衡的持续性。
- 容错处理
在多进程环境下,每个工作进程都应该有自己的异常处理机制,如上述HTTP请求异常处理部分。当一个工作进程发生未处理的异常并崩溃时,主进程的
cluster.on('exit', ...)
事件监听器会捕获到该事件,并重新启动一个新的工作进程,从而实现容错处理。这样,即使某个工作进程因为异常而停止工作,整个系统仍然能够继续处理请求,保证了高可用性。