Node.js之进程与子进程

17 阅读8分钟

Node.js之进程与子进程

目录

  1. 进程(Process)
  2. 子进程(Child Process)
  3. 进程和子进程区别
  4. 进程通信最佳实践

进程(Process)

在Node.js中,process是一个全局对象,提供了当前运行进程的信息和控制能力。每个Node.js应用程序都运行在单一进程中,通过process对象可以访问和控制该进程。

进程的常用场景

  • 环境配置管理:读取环境变量,根据不同环境执行不同逻辑
  • 命令行工具开发:处理命令行参数,构建CLI应用
  • 应用监控:监控内存使用、CPU使用率等性能指标
  • 优雅退出处理:处理进程退出信号,进行资源清理
  • 错误捕获:捕获未处理的异常和Promise rejection

进程中的常用属性和方法

属性/方法作用类型
process.pid获取进程IDNumber
process.argv获取命令行参数数组Array
process.env获取环境变量对象Object
process.cwd()获取当前工作目录Function
process.exit()终止进程Function
process.memoryUsage()获取内存使用情况Function
process.uptime()获取进程运行时间Function
process.platform获取操作系统平台String

示例

获取命令行参数
// 命令: node app.js --port 3000 --env production
console.log('命令行参数:', process.argv);
// 输出: ['node', '/path/to/app.js', '--port', '3000', '--env', 'production']

// 解析命令行参数
function parseArgs() {
    const args = process.argv.slice(2);
    const config = {};
    
    for (let i = 0; i < args.length; i += 2) {
        const key = args[i].replace('--', '');
        const value = args[i + 1];
        config[key] = value;
    }
    
    return config;
}

const config = parseArgs();
console.log('解析后配置:', config);
// 输出: { port: '3000', env: 'production' }

// 使用第三方库解析参数
const yargs = require('yargs');
const argv = yargs
    .option('port', {
        alias: 'p',
        description: '服务端口号',
        type: 'number',
        default: 3000
    })
    .option('env', {
        alias: 'e',
        description: '运行环境',
        type: 'string',
        default: 'development'
    })
    .help()
    .argv;

console.log(`服务启动在端口 ${argv.port},环境: ${argv.env}`);
读取环境变量
// 读取环境变量
console.log('数据库URL:', process.env.DATABASE_URL);
console.log('API密钥:', process.env.API_KEY);
console.log('运行环境:', process.env.NODE_ENV || 'development');

// 环境变量配置管理
class Config {
    constructor() {
        this.port = process.env.PORT || 3000;
        this.dbUrl = process.env.DATABASE_URL || 'mongodb://localhost:27017/myapp';
        this.jwtSecret = process.env.JWT_SECRET;
        this.nodeEnv = process.env.NODE_ENV || 'development';
        
        this.validate();
    }
    
    validate() {
        const required = ['JWT_SECRET'];
        const missing = required.filter(key => !process.env[key]);
        
        if (missing.length > 0) {
            console.error(`缺少必需的环境变量: ${missing.join(', ')}`);
            process.exit(1);
        }
    }
    
    isDevelopment() {
        return this.nodeEnv === 'development';
    }
    
    isProduction() {
        return this.nodeEnv === 'production';
    }
}

const config = new Config();
终止进程
// 优雅退出处理
class GracefulShutdown {
    constructor() {
        this.isShuttingDown = false;
        this.connections = new Set();
        this.setupSignalHandlers();
    }
    
    setupSignalHandlers() {
        // 处理SIGTERM信号(Docker、Kubernetes常用)
        process.on('SIGTERM', () => {
            console.log('收到SIGTERM信号,开始优雅关闭...');
            this.shutdown('SIGTERM');
        });
        
        // 处理SIGINT信号(Ctrl+C)
        process.on('SIGINT', () => {
            console.log('收到SIGINT信号,开始优雅关闭...');
            this.shutdown('SIGINT');
        });
        
        // 处理未捕获异常
        process.on('uncaughtException', (error) => {
            console.error('未捕获的异常:', error);
            this.shutdown('uncaughtException');
        });
        
        // 处理未处理的Promise rejection
        process.on('unhandledRejection', (reason, promise) => {
            console.error('未处理的Promise rejection:', reason);
            this.shutdown('unhandledRejection');
        });
    }
    
    async shutdown(signal) {
        if (this.isShuttingDown) {
            console.log('正在关闭中,忽略重复信号');
            return;
        }
        
        this.isShuttingDown = true;
        console.log(`开始优雅关闭进程 (信号: ${signal})`);
        
        try {
            // 停止接受新连接
            if (this.server) {
                this.server.close();
            }
            
            // 关闭现有连接
            const closePromises = Array.from(this.connections).map(conn => {
                return new Promise(resolve => {
                    conn.end(resolve);
                });
            });
            
            await Promise.all(closePromises);
            
            // 关闭数据库连接
            if (this.database) {
                await this.database.close();
            }
            
            console.log('优雅关闭完成');
            process.exit(0);
            
        } catch (error) {
            console.error('关闭过程出错:', error);
            process.exit(1);
        }
    }
}

// 监控进程性能
setInterval(() => {
    const memUsage = process.memoryUsage();
    const cpuUsage = process.cpuUsage();
    
    console.log('进程性能监控:', {
        pid: process.pid,
        uptime: process.uptime(),
        memory: {
            rss: Math.round(memUsage.rss / 1024 / 1024) + 'MB',
            heapUsed: Math.round(memUsage.heapUsed / 1024 / 1024) + 'MB',
            heapTotal: Math.round(memUsage.heapTotal / 1024 / 1024) + 'MB'
        },
        cpu: {
            user: cpuUsage.user,
            system: cpuUsage.system
        }
    });
}, 30000);

子进程(Child Process)

子进程是Node.js实现多进程的核心机制,允许在主进程之外创建新的进程来执行特定任务,从而避免阻塞主进程的事件循环。

子进程的使用场景

  • CPU密集型计算:图像处理、数据分析、加密解密等
  • 系统命令执行:文件操作、系统管理、脚本执行
  • 第三方程序调用:调用Python脚本、执行外部工具
  • 负载均衡:创建多个Worker进程处理请求
  • 任务隔离:将不稳定任务隔离到子进程中执行
  • 资源密集型任务:避免阻塞主进程的I/O操作

子进程模块的常用方法

Node.js的child_process模块提供了四个主要方法来创建子进程:

flowchart TD
    A[child_process模块] --> B[exec方法]
    A --> C[execFile方法]
    A --> D[spawn方法]
    A --> E[fork方法]
    
    B --> B1[缓冲输出]
    B --> B2[支持Shell语法]
    B --> B3[内存限制]
    
    C --> C1[直接执行文件]
    C --> C2[更安全]
    C --> C3[不支持Shell]
    
    D --> D1[流式输出]
    D --> D2[实时数据]
    D --> D3[长时间运行]
    
    E --> E1[Node.js专用]
    E --> E2[IPC通信]
    E --> E3[共享模块]
exec()方法

exec()方法创建一个Shell环境来执行命令,将输出缓冲到内存中,命令执行完毕后通过回调函数返回结果。

优点
  • 简单易用:语法简洁,适合快速执行命令
  • Shell支持:支持管道、重定向等Shell特性
  • 自动解析:自动处理命令行参数和环境变量
缺点
  • 内存限制:输出被缓冲在内存中,大量输出可能导致内存溢出
  • 安全风险:通过Shell执行,存在命令注入风险
  • 阻塞问题:无法实时获取输出,需要等待命令执行完毕
适用场景
  • 执行简单的系统命令
  • 输出量较小的命令
  • 需要使用Shell特性(管道、重定向等)
  • 快速原型开发和脚本编写
示例
const { exec } = require('child_process');
const util = require('util');
const execAsync = util.promisify(exec);

// 基础用法
exec('ls -la', (error, stdout, stderr) => {
    if (error) {
        console.error(`执行错误: ${error.message}`);
        return;
    }
    if (stderr) {
        console.error(`标准错误: ${stderr}`);
    }
    console.log(`输出:\n${stdout}`);
});

// 设置选项
exec('npm list --depth=0', {
    cwd: '/path/to/project',
    env: { ...process.env, NODE_ENV: 'production' },
    maxBuffer: 1024 * 1024,
    timeout: 10000
}, (error, stdout, stderr) => {
    if (error) {
        if (error.code === 'ETIMEDOUT') {
            console.error('命令执行超时');
        } else {
            console.error(`执行错误: ${error.message}`);
        }
        return;
    }
    console.log('项目依赖:', stdout);
});

// 使用Promise封装
async function runCommand(command, options = {}) {
    try {
        const { stdout, stderr } = await execAsync(command, {
            maxBuffer: 1024 * 1024,
            timeout: 30000,
            ...options
        });
        
        if (stderr && !options.ignoreStderr) {
            console.warn('警告:', stderr);
        }
        
        return stdout.trim();
    } catch (error) {
        throw new Error(`命令执行失败: ${error.message}`);
    }
}

// 实际应用示例
async function deployApplication() {
    try {
        console.log('开始部署应用...');
        
        // 拉取最新代码
        await runCommand('git pull origin main');
        console.log('✓ 代码更新完成');
        
        // 安装依赖
        await runCommand('npm install --production');
        console.log('✓ 依赖安装完成');
        
        // 构建应用
        await runCommand('npm run build');
        console.log('✓ 应用构建完成');
        
        // 重启服务
        await runCommand('pm2 restart app');
        console.log('✓ 服务重启完成');
        
        console.log('🎉 部署成功!');
        
    } catch (error) {
        console.error('❌ 部署失败:', error.message);
        process.exit(1);
    }
}
spawn()方法

spawn()方法创建一个子进程来执行指定程序,通过流的方式处理输入输出,适合长时间运行或大量数据处理的场景。

优点
  • 流式处理:实时处理输入输出,内存使用效率高
  • 实时反馈:可以实时获取命令执行过程中的输出
  • 灵活控制:可以控制子进程的标准输入、输出和错误流
  • 长时间运行:适合执行长时间运行的任务
缺点
  • 复杂性高:需要处理多个事件和流
  • 无Shell支持:不支持Shell语法特性
  • 手动处理:需要手动处理参数解析和输出缓冲
适用场景
  • 长时间运行的进程
  • 大量数据输出的命令
  • 需要实时交互的程序
  • 需要精确控制输入输出的场景
示例
const { spawn } = require('child_process');

// 基础用法
const ls = spawn('ls', ['-la', '/usr']);

ls.stdout.on('data', (data) => {
    console.log(`输出: ${data}`);
});

ls.stderr.on('data', (data) => {
    console.error(`错误: ${data}`);
});

ls.on('close', (code) => {
    console.log(`子进程退出,退出码: ${code}`);
});

// 高级用法:实时日志监控
class LogMonitor {
    constructor(logFile) {
        this.logFile = logFile;
        this.isRunning = false;
    }
    
    start() {
        if (this.isRunning) return;
        
        this.tailProcess = spawn('tail', ['-f', this.logFile]);
        this.isRunning = true;
        
        this.tailProcess.stdout.on('data', (data) => {
            const lines = data.toString().split('\n').filter(line => line.trim());
            lines.forEach(line => this.processLogLine(line));
        });
        
        this.tailProcess.stderr.on('data', (data) => {
            console.error(`日志监控错误: ${data}`);
        });
        
        this.tailProcess.on('close', (code) => {
            console.log(`日志监控进程退出,退出码: ${code}`);
            this.isRunning = false;
        });
        
        console.log(`开始监控日志文件: ${this.logFile}`);
    }
    
    processLogLine(line) {
        // 解析日志行
        try {
            const logEntry = JSON.parse(line);
            
            // 根据日志级别处理
            switch (logEntry.level) {
                case 'error':
                    console.error('🔴 错误日志:', logEntry.message);
                    this.sendAlert(logEntry);
                    break;
                case 'warn':
                    console.warn('🟡 警告日志:', logEntry.message);
                    break;
                case 'info':
                    console.log('🔵 信息日志:', logEntry.message);
                    break;
            }
        } catch (error) {
            // 非JSON格式日志
            console.log('📝 原始日志:', line);
        }
    }
    
    sendAlert(logEntry) {
        // 发送告警通知
        console.log('🚨 发送告警通知');
    }
    
    stop() {
        if (this.tailProcess && this.isRunning) {
            this.tailProcess.kill('SIGTERM');
        }
    }
}

// 文件处理示例
function compressFiles(sourceDir, targetFile) {
    return new Promise((resolve, reject) => {
        const tar = spawn('tar', ['-czf', targetFile, sourceDir]);
        
        let stderr = '';
        
        tar.stdout.on('data', (data) => {
            process.stdout.write('.');
        });
        
        tar.stderr.on('data', (data) => {
            stderr += data.toString();
        });
        
        tar.on('close', (code) => {
            if (code === 0) {
                console.log(`\n✓ 文件压缩完成: ${targetFile}`);
                resolve();
            } else {
                reject(new Error(`压缩失败: ${stderr}`));
            }
        });
        
        tar.on('error', reject);
    });
}

// 使用示例
async function backupProject() {
    try {
        const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
        const backupFile = `backup-${timestamp}.tar.gz`;
        
        console.log('开始项目备份...');
        await compressFiles('./project', backupFile);
        console.log('项目备份完成');
        
    } catch (error) {
        console.error('备份失败:', error.message);
    }
}
fork() 方法

fork()方法是spawn()的特殊版本,专门用于创建Node.js子进程,提供了内置的进程间通信(IPC)机制。

优点
  • 进程间通信:内置IPC通道,方便父子进程通信
  • Node.js专用:针对Node.js优化,共享模块缓存
  • 简单通信:使用send()message事件进行通信
  • 模块共享:子进程可以访问父进程的模块
缺点
  • 仅限Node.js:只能执行Node.js脚本
  • 资源消耗:创建完整的Node.js进程,资源消耗较大
  • 通信限制:IPC通信有数据大小限制
适用场景
  • CPU密集型Node.js任务
  • 需要进程间通信的场景
  • 多进程架构的Node.js应用
  • 任务队列处理
示例
// 主进程 (main.js)
const { fork } = require('child_process');
const path = require('path');

class TaskManager {
    constructor(maxWorkers = 4) {
        this.maxWorkers = maxWorkers;
        this.workers = [];
        this.taskQueue = [];
        this.activeTasks = new Map();
        
        this.initWorkers();
    }
    
    initWorkers() {
        for (let i = 0; i < this.maxWorkers; i++) {
            this.createWorker();
        }
    }
    
    createWorker() {
        const worker = fork(path.join(__dirname, 'worker.js'));
        
        worker.busy = false;
        worker.id = this.workers.length;
        
        // 监听工作进程消息
        worker.on('message', (message) => {
            this.handleWorkerMessage(worker, message);
        });
        
        // 监听工作进程错误
        worker.on('error', (error) => {
            console.error(`Worker ${worker.id} 错误:`, error);
            this.restartWorker(worker);
        });
        
        // 监听工作进程退出
        worker.on('exit', (code, signal) => {
            console.log(`Worker ${worker.id} 退出,代码: ${code}, 信号: ${signal}`);
            this.restartWorker(worker);
        });
        
        this.workers.push(worker);
        console.log(`Worker ${worker.id} 已创建`);
    }
    
    handleWorkerMessage(worker, message) {
        const { type, taskId, result, error, progress } = message;
        
        switch (type) {
            case 'taskComplete':
                worker.busy = false;
                const task = this.activeTasks.get(taskId);
                if (task) {
                    if (error) {
                        task.reject(new Error(error));
                    } else {
                        task.resolve(result);
                    }
                    this.activeTasks.delete(taskId);
                }
                this.processQueue();
                break;
                
            case 'progress':
                const progressTask = this.activeTasks.get(taskId);
                if (progressTask && progressTask.onProgress) {
                    progressTask.onProgress(progress);
                }
                break;
                
            case 'ready':
                console.log(`Worker ${worker.id} 准备就绪`);
                break;
        }
    }
    
    executeTask(taskType, data, onProgress) {
        return new Promise((resolve, reject) => {
            const taskId = Date.now() + Math.random();
            const task = {
                id: taskId,
                type: taskType,
                data,
                resolve,
                reject,
                onProgress
            };
            
            this.activeTasks.set(taskId, task);
            
            const availableWorker = this.workers.find(w => !w.busy);
            if (availableWorker) {
                this.assignTask(availableWorker, task);
            } else {
                this.taskQueue.push(task);
            }
        });
    }
    
    assignTask(worker, task) {
        worker.busy = true;
        worker.send({
            type: 'executeTask',
            taskId: task.id,
            taskType: task.type,
            data: task.data
        });
    }
    
    processQueue() {
        if (this.taskQueue.length === 0) return;
        
        const availableWorker = this.workers.find(w => !w.busy);
        if (availableWorker) {
            const task = this.taskQueue.shift();
            this.assignTask(availableWorker, task);
        }
    }
    
    restartWorker(oldWorker) {
        const index = this.workers.indexOf(oldWorker);
        if (index !== -1) {
            this.workers.splice(index, 1);
            oldWorker.kill();
        }
        
        this.createWorker();
    }
    
    shutdown() {
        this.workers.forEach(worker => {
            worker.kill('SIGTERM');
        });
    }
}

// 使用示例
const taskManager = new TaskManager(4);

async function main() {
    try {
        // CPU密集型任务:计算斐波那契数列
        console.log('开始计算斐波那契数列...');
        const fibResult = await taskManager.executeTask('fibonacci', { n: 40 });
        console.log(`斐波那契结果: ${fibResult}`);
        
        // 图像处理任务
        console.log('开始图像处理任务...');
        const imageResult = await taskManager.executeTask('processImage', {
            imagePath: './input.jpg',
            filters: ['blur', 'sharpen']
        }, (progress) => {
            console.log(`图像处理进度: ${progress}%`);
        });
        console.log('图像处理完成:', imageResult);
        
        // 数据分析任务
        console.log('开始数据分析...');
        const analysisResult = await taskManager.executeTask('analyzeData', {
            dataSet: Array.from({length: 1000000}, () => Math.random())
        });
        console.log('数据分析结果:', analysisResult);
        
    } catch (error) {
        console.error('任务执行失败:', error);
    }
}

main();

// 优雅关闭
process.on('SIGINT', () => {
    console.log('收到SIGINT信号,关闭任务管理器...');
    taskManager.shutdown();
    process.exit(0);
});
// 工作进程 (worker.js)
class Worker {
    constructor() {
        this.setupMessageHandler();
        this.sendMessage('ready');
    }
    
    setupMessageHandler() {
        process.on('message', (message) => {
            this.handleMessage(message);
        });
    }
    
    async handleMessage(message) {
        const { type, taskId, taskType, data } = message;
        
        if (type === 'executeTask') {
            try {
                const result = await this.executeTask(taskType, data, taskId);
                this.sendMessage('taskComplete', taskId, result);
            } catch (error) {
                this.sendMessage('taskComplete', taskId, null, error.message);
            }
        }
    }
    
    async executeTask(taskType, data, taskId) {
        switch (taskType) {
            case 'fibonacci':
                return this.calculateFibonacci(data.n);
                
            case 'processImage':
                return this.processImage(data, taskId);
                
            case 'analyzeData':
                return this.analyzeData(data.dataSet, taskId);
                
            default:
                throw new Error(`未知任务类型: ${taskType}`);
        }
    }
    
    calculateFibonacci(n) {
        if (n < 2) return n;
        return this.calculateFibonacci(n - 1) + this.calculateFibonacci(n - 2);
    }
    
    async processImage(data, taskId) {
        const { imagePath, filters } = data;
        
        // 模拟图像处理过程
        for (let i = 0; i < filters.length; i++) {
            const filter = filters[i];
            const progress = Math.round((i + 1) / filters.length * 100);
            
            // 发送进度更新
            this.sendMessage('progress', taskId, null, null, progress);
            
            // 模拟处理时间
            await new Promise(resolve => setTimeout(resolve, 1000));
            
            console.log(`Worker ${process.pid} 应用滤镜: ${filter}`);
        }
        
        return {
            outputPath: `processed_${Date.now()}.jpg`,
            appliedFilters: filters,
            processTime: Date.now()
        };
    }
    
    async analyzeData(dataSet, taskId) {
        const chunkSize = Math.floor(dataSet.length / 10);
        let sum = 0;
        let min = Infinity;
        let max = -Infinity;
        
        for (let i = 0; i < dataSet.length; i += chunkSize) {
            const chunk = dataSet.slice(i, i + chunkSize);
            
            for (const value of chunk) {
                sum += value;
                min = Math.min(min, value);
                max = Math.max(max, value);
            }
            
            // 发送进度更新
            const progress = Math.round((i + chunkSize) / dataSet.length * 100);
            this.sendMessage('progress', taskId, null, null, progress);
        }
        
        const average = sum / dataSet.length;
        const variance = dataSet.reduce((acc, val) => acc + Math.pow(val - average, 2), 0) / dataSet.length;
        
        return {
            count: dataSet.length,
            sum,
            average,
            min,
            max,
            variance,
            standardDeviation: Math.sqrt(variance)
        };
    }
    
    sendMessage(type, taskId = null, result = null, error = null, progress = null) {
        process.send({
            type,
            taskId,
            result,
            error,
            progress,
            workerId: process.pid
        });
    }
}

new Worker();

三种方法区别对比

特性exec()spawn()fork()
输出处理缓冲输出流式输出流式输出
内存使用高(缓冲)低(流式)中等
Shell支持
实时输出
进程通信
执行对象Shell命令可执行文件Node.js脚本
安全性
适用场景简单命令长时间进程CPU密集型任务
资源消耗
错误处理回调事件事件+IPC
flowchart TD
    A[需要执行子进程] --> B{执行什么类型的任务?}
    
    B -->|简单Shell命令| C[使用 exec方法]
    B -->|可执行文件/长时间运行| D[使用 spawn方法]
    B -->|Node.js脚本/CPU密集型| E[使用 fork方法]
    
    C --> F{输出量大吗?}
    F -->|是| G[考虑使用 spawn方法]
    F -->|否| H[exec方法 适合]
    
    D --> I{需要实时交互?}
    I -->|是| J[spawn方法 最佳选择]
    I -->|否| K[考虑其他方案]
    
    E --> L{需要进程间通信?}
    L -->|是| M[fork方法 最佳选择]
    L -->|否| N[考虑 spawn方法]

进程和子进程区别

核心差异对比

维度进程(Process)子进程(Child Process)
定义当前运行的Node.js实例由主进程创建的新进程
数量单一进程可创建多个
内存空间独立内存空间各自独立的内存空间
生命周期应用程序整个生命周期可控制创建和销毁
通信方式无需通信(同一进程)IPC、标准流、文件等
资源共享全局共享隔离的资源空间
崩溃影响整个应用崩溃仅子进程崩溃,主进程可恢复
用途主要业务逻辑特定任务、CPU密集型计算

进程间关系图

flowchart TD
    A[主进程 - Node.js Application] --> B[process对象]
    A --> C[创建子进程]
    
    B --> D[process.env 环境变量]
    B --> E[process.argv 命令行参数]
    B --> F[process.pid 进程ID]
    B --> G[process.memoryUsage 内存使用]
    
    C --> H[子进程1 - exec]
    C --> I[子进程2 - spawn]
    C --> J[子进程3 - fork]
    
    H --> K[执行Shell命令]
    I --> L[执行系统程序]
    J --> M[执行Node.js脚本]
    
    A -.-> N[IPC通信]
    J -.-> N
    
    A -.-> O[标准流通信]
    H -.-> O
    I -.-> O

使用场景决策树

flowchart TD
    A[需要处理任务] --> B{任务类型?}
    
    B -->|配置管理/环境变量| C[使用 process 对象]
    B -->|CPU密集型计算| D[创建子进程]
    B -->|I/O密集型操作| E[主进程处理]
    
    C --> F[process.env, process.argv等]
    E --> G[使用异步I/O操作]
    
    D --> H{需要进程间通信?}
    H -->|是| I[使用 fork方法]
    H -->|否| J{执行什么程序?}
    
    J -->|Node.js脚本| I
    J -->|系统命令| K[使用 exec方法]
    J -->|可执行文件| L[使用 spawn方法]
    
    I --> M[建立IPC通道]
    K --> N[获取命令输出]
    L --> O[处理程序流]

进程通信最佳实践

1. 错误处理和监控

class ProcessManager {
    constructor() {
        this.processes = new Map();
        this.setupGlobalHandlers();
    }
    
    setupGlobalHandlers() {
        // 全局错误捕获
        process.on('uncaughtException', (error) => {
            console.error('未捕获异常:', error);
            this.gracefulShutdown();
        });
        
        process.on('unhandledRejection', (reason, promise) => {
            console.error('未处理的Promise rejection:', reason);
            this.gracefulShutdown();
        });
        
        // 进程信号处理
        ['SIGTERM', 'SIGINT', 'SIGUSR2'].forEach(signal => {
            process.on(signal, () => {
                console.log(`收到 ${signal} 信号`);
                this.gracefulShutdown();
            });
        });
    }
    
    createChildProcess(name, scriptPath, options = {}) {
        const child = fork(scriptPath, [], {
            silent: false,
            ...options
        });
        
        child.name = name;
        child.startTime = Date.now();
        child.restartCount = 0;
        
        // 子进程事件监听
        child.on('message', (msg) => {
            this.handleChildMessage(child, msg);
        });
        
        child.on('error', (error) => {
            console.error(`子进程 ${name} 错误:`, error);
        });
        
        child.on('exit', (code, signal) => {
            console.log(`子进程 ${name} 退出,代码: ${code}`);
            this.handleChildExit(child, code, signal);
        });
        
        this.processes.set(name, child);
        return child;
    }
    
    handleChildMessage(child, message) {
        const { type, data } = message;
        
        switch (type) {
            case 'health':
                console.log(`子进程 ${child.name} 健康状态:`, data);
                break;
            case 'metrics':
                this.recordMetrics(child.name, data);
                break;
            case 'error':
                console.error(`子进程 ${child.name} 报告错误:`, data);
                break;
        }
    }
    
    handleChildExit(child, code, signal) {
        if (code !== 0 && child.restartCount < 3) {
            child.restartCount++;
            console.log(`重启子进程 ${child.name},第 ${child.restartCount} 次`);
            
            setTimeout(() => {
                const newChild = this.createChildProcess(
                    child.name,
                    child.spawnfile,
                    { env: child.env }
                );
                newChild.restartCount = child.restartCount;
            }, 1000 * child.restartCount);
        }
    }
    
    recordMetrics(processName, metrics) {
        // 记录性能指标
        console.log(`进程 ${processName} 指标:`, metrics);
    }
    
    async gracefulShutdown() {
        console.log('开始优雅关闭所有子进程...');
        
        const shutdownPromises = Array.from(this.processes.values()).map(child => {
            return new Promise((resolve) => {
                child.send({ type: 'shutdown' });
                
                const timeout = setTimeout(() => {
                    child.kill('SIGKILL');
                    resolve();
                }, 5000);
                
                child.on('exit', () => {
                    clearTimeout(timeout);
                    resolve();
                });
            });
        });
        
        await Promise.all(shutdownPromises);
        console.log('所有子进程已关闭');
        process.exit(0);
    }
}

// 使用示例
const processManager = new ProcessManager();

// 创建不同类型的子进程
processManager.createChildProcess('worker1', './cpu-worker.js');
processManager.createChildProcess('logger', './log-processor.js');
processManager.createChildProcess('monitor', './health-monitor.js');

2. 性能监控和资源管理

// 子进程性能监控
class ChildProcessMonitor {
    constructor(child) {
        this.child = child;
        this.metrics = {
            memory: [],
            cpu: [],
            messages: 0,
            errors: 0
        };
        
        this.startMonitoring();
    }
    
    startMonitoring() {
        // 定期收集性能指标
        setInterval(() => {
            this.child.send({ type: 'getMetrics' });
        }, 5000);
        
        this.child.on('message', (msg) => {
            if (msg.type === 'metrics') {
                this.recordMetrics(msg.data);
            }
        });
    }
    
    recordMetrics(data) {
        this.metrics.memory.push(data.memory);
        this.metrics.cpu.push(data.cpu);
        this.metrics.messages++;
        
        // 保持最近100个数据点
        if (this.metrics.memory.length > 100) {
            this.metrics.memory.shift();
            this.metrics.cpu.shift();
        }
        
        // 检查资源使用告警
        this.checkAlerts(data);
    }
    
    checkAlerts(data) {
        // 内存使用告警
        if (data.memory.rss > 500 * 1024 * 1024) { // 500MB
            console.warn(`⚠️ 子进程内存使用过高: ${data.memory.rss / 1024 / 1024}MB`);
        }
        
        // CPU使用告警
        if (data.cpu.percent > 80) {
            console.warn(`⚠️ 子进程CPU使用率过高: ${data.cpu.percent}%`);
        }
    }
    
    getStats() {
        const memoryAvg = this.metrics.memory.reduce((sum, m) => sum + m.rss, 0) / this.metrics.memory.length;
        const cpuAvg = this.metrics.cpu.reduce((sum, c) => sum + c.percent, 0) / this.metrics.cpu.length;
        
        return {
            averageMemory: Math.round(memoryAvg / 1024 / 1024) + 'MB',
            averageCPU: Math.round(cpuAvg) + '%',
            totalMessages: this.metrics.messages,
            totalErrors: this.metrics.errors
        };
    }
}