面试题答案
一键面试1. 进程间通信
- 使用
process.send()
和message
事件:在工作进程中,当捕获到未捕获的异常时,通过process.send()
向主进程发送包含错误信息的消息。例如:
process.on('uncaughtException', (err) => {
process.send({
type: 'error',
error: err
});
// 这里可以选择是否立即关闭工作进程
});
在主进程中,通过监听 message
事件来接收这些错误信息:
worker.on('message', (msg) => {
if (msg.type === 'error') {
// 处理错误
}
});
2. 错误检测
- 工作进程检测:在每个工作进程中,使用
process.on('uncaughtException')
捕获未捕获的异常,这可以检测到同步代码以及异步回调中抛出的异常。 - 主进程检测:主进程除了通过
message
事件接收工作进程传来的错误,还可以使用worker.on('exit')
事件来检测工作进程意外退出的情况。例如:
worker.on('exit', (code, signal) => {
if (code!== 0 &&!isGracefulExit) {
// 工作进程异常退出,进行相应处理
}
});
3. 恢复策略
- 重启工作进程:当主进程接收到工作进程的错误消息或者检测到工作进程异常退出时,主进程可以选择重启该工作进程。例如:
const cluster = require('cluster');
if (cluster.isMaster) {
const worker = cluster.fork();
worker.on('message', (msg) => {
if (msg.type === 'error') {
console.error('Worker reported an error:', msg.error);
worker.kill();
const newWorker = cluster.fork();
}
});
worker.on('exit', (code, signal) => {
if (code!== 0 &&!isGracefulExit) {
console.error('Worker exited abnormally. Restarting...');
const newWorker = cluster.fork();
}
});
}
- 负载均衡调整:在重启工作进程的同时,可以暂时调整负载均衡策略,减少对刚出现错误的工作进程(即将重启)的请求分配。例如,使用
cluster.schedulingPolicy = cluster.SCHED_NONE
暂时禁用该工作进程的请求分配,直到重启完成。然后再将调度策略恢复为正常,如cluster.schedulingPolicy = cluster.SCHED_RR
。 - 记录错误日志:无论是工作进程还是主进程,在处理错误时都应该记录详细的错误日志,包括错误堆栈信息、发生时间等,以便后续分析问题。可以使用
console.error()
或者专业的日志库如winston
来记录日志。例如:
const winston = require('winston');
const logger = winston.createLogger({
level: 'error',
format: winston.format.json(),
transports: [
new winston.transport.Console()
]
});
process.on('uncaughtException', (err) => {
logger.error('Uncaught Exception in worker:', err.message, err.stack);
process.send({
type: 'error',
error: err
});
});