轩辕李的博客 轩辕李的博客
首页
  • Java
  • Spring
  • 其他语言
  • 工具
  • HTML&CSS
  • JavaScript
  • 分布式
  • 代码质量管理
  • 基础
  • 操作系统
  • 计算机网络
  • 编程范式
  • 安全
  • 中间件
  • 心得
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

轩辕李

勇猛精进,星辰大海
首页
  • Java
  • Spring
  • 其他语言
  • 工具
  • HTML&CSS
  • JavaScript
  • 分布式
  • 代码质量管理
  • 基础
  • 操作系统
  • 计算机网络
  • 编程范式
  • 安全
  • 中间件
  • 心得
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • JavaScript

  • TypeScript

  • Node.js

    • Node.js快速入门
    • Node.js高级特性详解
      • 一、Node.js 事件循环
        • 事件循环的六个阶段
        • 微任务队列
        • setTimeout vs setImmediate
        • process.nextTick 陷阱
        • 事件循环实战
      • 二、流(Stream)
        • 流的类型
        • 可读流
        • 可写流
        • 管道(Pipe)
        • 背压(Backpressure)处理
        • 自定义可读流
        • 自定义可写流
        • 自定义转换流
      • 三、缓冲区(Buffer)
        • Buffer 基础
        • Buffer 操作
        • 字符编码
        • Buffer 与 TypedArray
      • 四、子进程(Child Process)
        • exec(执行 shell 命令)
        • spawn(流式输出)
        • execFile(执行文件)
        • fork(创建 Node.js 子进程)
      • 五、集群(Cluster)
        • 基本用法
        • 进程间通信
        • 负载均衡
      • 六、性能优化
        • 使用集群
        • 缓存
        • 连接池
        • 压缩响应
        • 避免阻塞事件循环
        • 使用流处理大文件
        • 内存管理
      • 七、进程管理
        • process 对象
        • 优雅退出
      • 八、定时器高级用法
        • 高精度计时
        • setImmediate vs process.nextTick
      • 九、异步编程进阶
        • async_hooks(异步资源追踪)
        • Worker Threads(工作线程)
        • 线程池
      • 十、安全最佳实践
        • 输入验证
        • 防止 SQL 注入
        • 防止 XSS
        • 速率限制
        • 环境变量保护
      • 十一、总结
  • Vue.js

  • 工程化

  • 浏览器与Web API

  • 前端
  • Node.js
轩辕李
2025-04-22
目录

Node.js高级特性详解

本文深入探讨 Node.js 的高级特性,包括事件循环、流、缓冲区、子进程、集群、性能优化等核心概念。这些知识是构建高性能、可扩展 Node.js 应用的关键。

# 一、Node.js 事件循环

# 事件循环的六个阶段

Node.js 的事件循环不同于浏览器,它有 6 个阶段:

   ┌───────────────────────────┐
┌─>│           timers          │  执行 setTimeout/setInterval 回调
│  └─────────────┬─────────────┘
│  ┌─────────────┴─────────────┐
│  │     pending callbacks     │  执行延迟到下一个循环的 I/O 回调
│  └─────────────┬─────────────┘
│  ┌─────────────┴─────────────┐
│  │       idle, prepare       │  内部使用
│  └─────────────┬─────────────┘      ┌───────────────┐
│  ┌─────────────┴─────────────┐      │   incoming:   │
│  │           poll            │<─────┤  connections, │
│  └─────────────┬─────────────┘      │   data, etc.  │
│  ┌─────────────┴─────────────┐      └───────────────┘
│  │           check           │  执行 setImmediate 回调
│  └─────────────┬─────────────┘
│  ┌─────────────┴─────────────┐
└──┤      close callbacks      │  执行 close 事件回调
   └───────────────────────────┘

# 微任务队列

在每个阶段之间,都会执行微任务队列:

  1. process.nextTick():最高优先级,当前阶段结束后立即执行
  2. Promise.then/catch/finally:次高优先级
console.log('1');

setTimeout(() => console.log('2'), 0);
setImmediate(() => console.log('3'));

process.nextTick(() => console.log('4'));
Promise.resolve().then(() => console.log('5'));

console.log('6');

// 输出:1 → 6 → 4 → 5 → 2 → 3(或 3 → 2,取决于进入事件循环的时机)

# setTimeout vs setImmediate

// 在主模块中,顺序不确定
setTimeout(() => console.log('timeout'), 0);
setImmediate(() => console.log('immediate'));

// 在 I/O 回调中,setImmediate 总是先执行
const fs = require('fs');

fs.readFile(__filename, () => {
    setTimeout(() => console.log('timeout'), 0);
    setImmediate(() => console.log('immediate'));
    // 输出:immediate → timeout
});

# process.nextTick 陷阱

// ❌ 错误:无限递归,阻塞事件循环
function recurse() {
    process.nextTick(recurse);
}
recurse();

// ✅ 正确:使用 setImmediate
function recurse() {
    setImmediate(recurse); // 允许其他阶段执行
}
recurse();

# 事件循环实战

const fs = require('fs');

console.log('Start');

// 1. timers 阶段
setTimeout(() => {
    console.log('setTimeout');
}, 0);

// 2. check 阶段
setImmediate(() => {
    console.log('setImmediate');
});

// 3. poll 阶段(I/O 操作)
fs.readFile(__filename, () => {
    console.log('readFile');
    
    setTimeout(() => console.log('readFile - setTimeout'), 0);
    setImmediate(() => console.log('readFile - setImmediate'));
    process.nextTick(() => console.log('readFile - nextTick'));
});

// 4. 微任务
process.nextTick(() => {
    console.log('nextTick 1');
    process.nextTick(() => console.log('nextTick 2'));
});

Promise.resolve().then(() => {
    console.log('Promise 1');
}).then(() => {
    console.log('Promise 2');
});

console.log('End');

// 可能输出:
// Start
// End
// nextTick 1
// nextTick 2
// Promise 1
// Promise 2
// setTimeout(或 setImmediate)
// setImmediate(或 setTimeout)
// readFile
// readFile - nextTick
// readFile - setImmediate
// readFile - setTimeout

# 二、流(Stream)

# 流的类型

Node.js 中有四种基本流:

  1. Readable:可读流(fs.createReadStream)
  2. Writable:可写流(fs.createWriteStream)
  3. Duplex:双工流(net.Socket)
  4. Transform:转换流(zlib.createGzip)

# 可读流

const fs = require('fs');

const readStream = fs.createReadStream('large-file.txt', {
    encoding: 'utf8',
    highWaterMark: 64 * 1024 // 缓冲区大小 64KB
});

readStream.on('data', (chunk) => {
    console.log(`接收到 ${chunk.length} 字节数据`);
});

readStream.on('end', () => {
    console.log('读取完成');
});

readStream.on('error', (err) => {
    console.error('读取错误:', err);
});

// 暂停和恢复
readStream.pause();
setTimeout(() => {
    readStream.resume();
}, 1000);

# 可写流

const fs = require('fs');

const writeStream = fs.createWriteStream('output.txt', {
    encoding: 'utf8'
});

writeStream.write('Hello, ');
writeStream.write('Node.js!\n');

// 结束写入
writeStream.end('Goodbye!\n');

writeStream.on('finish', () => {
    console.log('写入完成');
});

writeStream.on('error', (err) => {
    console.error('写入错误:', err);
});

# 管道(Pipe)

管道是连接流的最佳方式:

const fs = require('fs');

// 复制文件
const readStream = fs.createReadStream('source.txt');
const writeStream = fs.createWriteStream('dest.txt');

readStream.pipe(writeStream);

// 链式管道
const zlib = require('zlib');

fs.createReadStream('input.txt')
    .pipe(zlib.createGzip())                    // 压缩
    .pipe(fs.createWriteStream('input.txt.gz'));

// 解压
fs.createReadStream('input.txt.gz')
    .pipe(zlib.createGunzip())                  // 解压
    .pipe(fs.createWriteStream('output.txt'));

# 背压(Backpressure)处理

const fs = require('fs');

const readStream = fs.createReadStream('large-file.txt');
const writeStream = fs.createWriteStream('output.txt');

readStream.on('data', (chunk) => {
    // write() 返回 false 表示缓冲区已满
    const canContinue = writeStream.write(chunk);
    
    if (!canContinue) {
        console.log('缓冲区已满,暂停读取');
        readStream.pause();
    }
});

// 缓冲区清空后恢复读取
writeStream.on('drain', () => {
    console.log('缓冲区已清空,恢复读取');
    readStream.resume();
});

readStream.on('end', () => {
    writeStream.end();
});

// ✅ 更简单的方式:使用 pipe(自动处理背压)
readStream.pipe(writeStream);

# 自定义可读流

const { Readable } = require('stream');

class CounterStream extends Readable {
    constructor(max, options) {
        super(options);
        this.max = max;
        this.current = 1;
    }
    
    _read() {
        if (this.current <= this.max) {
            this.push(`${this.current}\n`);
            this.current++;
        } else {
            this.push(null); // 结束流
        }
    }
}

const counter = new CounterStream(5);

counter.on('data', (chunk) => {
    console.log('Data:', chunk.toString());
});

counter.on('end', () => {
    console.log('Done');
});

# 自定义可写流

const { Writable } = require('stream');

class ConsoleStream extends Writable {
    _write(chunk, encoding, callback) {
        console.log(`Writing: ${chunk.toString()}`);
        callback();
    }
}

const consoleStream = new ConsoleStream();

consoleStream.write('Hello, ');
consoleStream.write('Node.js!\n');
consoleStream.end();

# 自定义转换流

const { Transform } = require('stream');

class UpperCaseTransform extends Transform {
    _transform(chunk, encoding, callback) {
        const upperCased = chunk.toString().toUpperCase();
        this.push(upperCased);
        callback();
    }
}

const upperCaseStream = new UpperCaseTransform();

process.stdin
    .pipe(upperCaseStream)
    .pipe(process.stdout);

# 三、缓冲区(Buffer)

# Buffer 基础

Buffer 是用于处理二进制数据的类,类似于数组:

// 创建 Buffer
const buf1 = Buffer.from('Hello');
const buf2 = Buffer.from([72, 101, 108, 108, 111]);
const buf3 = Buffer.alloc(10);        // 分配 10 字节,填充 0
const buf4 = Buffer.allocUnsafe(10);  // 分配 10 字节,未初始化(性能更好)

// 查看内容
console.log(buf1);           // <Buffer 48 65 6c 6c 6f>
console.log(buf1.toString()); // 'Hello'
console.log(buf1.length);    // 5

// 访问和修改
console.log(buf1[0]);        // 72('H' 的 ASCII 码)
buf1[0] = 74;                // 修改为 'J'
console.log(buf1.toString()); // 'Jello'

# Buffer 操作

const buf = Buffer.from('Hello, Node.js!');

// 切片
const sliced = buf.subarray(0, 5);
console.log(sliced.toString()); // 'Hello'

// 拼接
const buf1 = Buffer.from('Hello, ');
const buf2 = Buffer.from('Node.js!');
const combined = Buffer.concat([buf1, buf2]);
console.log(combined.toString()); // 'Hello, Node.js!'

// 比较
const bufA = Buffer.from('abc');
const bufB = Buffer.from('abcd');
console.log(bufA.compare(bufB)); // -1(bufA < bufB)
console.log(bufA.equals(bufB));  // false

// 填充
const buf3 = Buffer.alloc(10);
buf3.fill('a');
console.log(buf3.toString()); // 'aaaaaaaaaa'

// 复制
const source = Buffer.from('Hello');
const target = Buffer.alloc(10);
source.copy(target, 0);
console.log(target.toString()); // 'Hello\0\0\0\0\0'

# 字符编码

// 支持的编码:utf8, ascii, base64, hex, binary 等
const buf = Buffer.from('你好', 'utf8');
console.log(buf);                        // <Buffer e4 bd a0 e5 a5 bd>
console.log(buf.toString('utf8'));       // '你好'
console.log(buf.toString('hex'));        // 'e4bda0e5a5bd'
console.log(buf.toString('base64'));     // '5L2g5aW9'

// Base64 编解码
const base64 = Buffer.from('Hello').toString('base64');
console.log(base64);                     // 'SGVsbG8='
const decoded = Buffer.from(base64, 'base64').toString();
console.log(decoded);                    // 'Hello'

# Buffer 与 TypedArray

// Buffer 继承自 Uint8Array
const buf = Buffer.from([1, 2, 3, 4]);
console.log(buf instanceof Uint8Array); // true

// 转换为 TypedArray
const uint16 = new Uint16Array(buf.buffer, buf.byteOffset, buf.length / 2);
console.log(uint16); // Uint16Array [ 513, 1027 ](小端序)

# 四、子进程(Child Process)

# exec(执行 shell 命令)

const { exec } = require('child_process');

exec('ls -lh', (error, stdout, stderr) => {
    if (error) {
        console.error('执行错误:', error);
        return;
    }
    if (stderr) {
        console.error('标准错误:', stderr);
    }
    console.log('标准输出:', stdout);
});

// Promise 版本
const util = require('util');
const execPromise = util.promisify(exec);

async function run() {
    try {
        const { stdout, stderr } = await execPromise('ls -lh');
        console.log(stdout);
    } catch (error) {
        console.error('执行错误:', error);
    }
}

run();

# spawn(流式输出)

const { spawn } = require('child_process');

const ls = spawn('ls', ['-lh', '/usr']);

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

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

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

// 管道到父进程
const grep = spawn('grep', ['root']);
ls.stdout.pipe(grep.stdin);
grep.stdout.pipe(process.stdout);

# execFile(执行文件)

const { execFile } = require('child_process');

execFile('node', ['--version'], (error, stdout, stderr) => {
    if (error) {
        console.error('执行错误:', error);
        return;
    }
    console.log('Node.js 版本:', stdout);
});

# fork(创建 Node.js 子进程)

// parent.js
const { fork } = require('child_process');

const child = fork('child.js');

// 发送消息给子进程
child.send({ type: 'start', data: 'Hello' });

// 接收子进程消息
child.on('message', (msg) => {
    console.log('父进程接收到消息:', msg);
});

child.on('exit', (code) => {
    console.log('子进程退出,退出码:', code);
});
// child.js
process.on('message', (msg) => {
    console.log('子进程接收到消息:', msg);
    
    // 发送消息给父进程
    process.send({ type: 'response', data: msg.data.toUpperCase() });
});

// 子进程执行耗时任务
function heavyTask() {
    let result = 0;
    for (let i = 0; i < 1e9; i++) {
        result += i;
    }
    return result;
}

const result = heavyTask();
process.send({ type: 'result', data: result });

# 五、集群(Cluster)

# 基本用法

利用多核 CPU,提高应用性能:

const cluster = require('cluster');
const http = require('http');
const os = require('os');

if (cluster.isMaster) {
    // 主进程
    const numCPUs = os.cpus().length;
    console.log(`主进程 ${process.pid} 正在运行`);
    console.log(`启动 ${numCPUs} 个工作进程`);
    
    // 创建工作进程
    for (let i = 0; i < numCPUs; i++) {
        cluster.fork();
    }
    
    // 工作进程退出时重启
    cluster.on('exit', (worker, code, signal) => {
        console.log(`工作进程 ${worker.process.pid} 已退出`);
        console.log('启动新的工作进程...');
        cluster.fork();
    });
} else {
    // 工作进程
    const server = http.createServer((req, res) => {
        res.writeHead(200);
        res.end(`由进程 ${process.pid} 处理\n`);
    });
    
    server.listen(3000, () => {
        console.log(`工作进程 ${process.pid} 已启动`);
    });
}

# 进程间通信

if (cluster.isMaster) {
    const worker = cluster.fork();
    
    // 发送消息给工作进程
    worker.send({ type: 'task', data: 'Do something' });
    
    // 接收工作进程消息
    worker.on('message', (msg) => {
        console.log('主进程接收到消息:', msg);
    });
} else {
    // 接收主进程消息
    process.on('message', (msg) => {
        console.log('工作进程接收到消息:', msg);
        
        // 发送消息给主进程
        process.send({ type: 'response', data: 'Task completed' });
    });
}

# 负载均衡

Node.js 的集群模块默认使用轮询(round-robin)负载均衡策略:

if (cluster.isMaster) {
    const numWorkers = 4;
    
    for (let i = 0; i < numWorkers; i++) {
        const worker = cluster.fork();
        console.log(`启动工作进程 ${worker.process.pid}`);
    }
    
    // 监控工作进程
    cluster.on('online', (worker) => {
        console.log(`工作进程 ${worker.process.pid} 在线`);
    });
    
    cluster.on('listening', (worker, address) => {
        console.log(`工作进程 ${worker.process.pid} 监听端口 ${address.port}`);
    });
} else {
    const express = require('express');
    const app = express();
    
    app.get('/', (req, res) => {
        res.send(`由进程 ${process.pid} 处理`);
    });
    
    app.listen(3000);
}

# 六、性能优化

# 使用集群

如上所示,利用多核 CPU 提高性能。

# 缓存

const NodeCache = require('node-cache');
const cache = new NodeCache({ stdTTL: 100 });

function getUser(id) {
    // 检查缓存
    const cached = cache.get(`user_${id}`);
    if (cached) {
        console.log('从缓存读取');
        return cached;
    }
    
    // 模拟数据库查询
    const user = { id, name: `User ${id}` };
    
    // 写入缓存
    cache.set(`user_${id}`, user);
    
    return user;
}

console.log(getUser(1)); // 数据库查询
console.log(getUser(1)); // 从缓存读取

# 连接池

// 数据库连接池示例(以 MySQL 为例)
const mysql = require('mysql2/promise');

const pool = mysql.createPool({
    host: 'localhost',
    user: 'root',
    password: 'password',
    database: 'mydb',
    connectionLimit: 10,      // 最大连接数
    waitForConnections: true, // 等待可用连接
    queueLimit: 0            // 队列限制
});

async function query() {
    const connection = await pool.getConnection();
    try {
        const [rows] = await connection.query('SELECT * FROM users');
        return rows;
    } finally {
        connection.release(); // 释放连接回池
    }
}

# 压缩响应

const express = require('express');
const compression = require('compression');

const app = express();

// 启用 gzip 压缩
app.use(compression());

app.get('/data', (req, res) => {
    const largeData = { items: new Array(10000).fill('data') };
    res.json(largeData);
});

app.listen(3000);

# 避免阻塞事件循环

// ❌ 错误:阻塞事件循环
app.get('/bad', (req, res) => {
    let result = 0;
    for (let i = 0; i < 1e9; i++) {
        result += i;
    }
    res.json({ result });
});

// ✅ 正确:使用子进程
const { fork } = require('child_process');

app.get('/good', (req, res) => {
    const worker = fork('heavy-task.js');
    
    worker.on('message', (result) => {
        res.json({ result });
        worker.kill();
    });
    
    worker.send({ task: 'calculate' });
});

# 使用流处理大文件

const express = require('express');
const fs = require('fs');

const app = express();

// ❌ 错误:一次性读取大文件
app.get('/bad', (req, res) => {
    const data = fs.readFileSync('large-file.txt', 'utf8');
    res.send(data);
});

// ✅ 正确:使用流
app.get('/good', (req, res) => {
    const stream = fs.createReadStream('large-file.txt', 'utf8');
    stream.pipe(res);
});

app.listen(3000);

# 内存管理

// 监控内存使用
function logMemoryUsage() {
    const usage = process.memoryUsage();
    console.log({
        rss: `${Math.round(usage.rss / 1024 / 1024)} MB`,        // 常驻集大小
        heapTotal: `${Math.round(usage.heapTotal / 1024 / 1024)} MB`, // 堆总大小
        heapUsed: `${Math.round(usage.heapUsed / 1024 / 1024)} MB`,   // 堆使用量
        external: `${Math.round(usage.external / 1024 / 1024)} MB`    // C++ 对象
    });
}

setInterval(logMemoryUsage, 5000);

// 手动触发垃圾回收(需要 --expose-gc 标志)
// node --expose-gc app.js
if (global.gc) {
    global.gc();
    console.log('手动触发垃圾回收');
}

# 七、进程管理

# process 对象

// 进程信息
console.log('进程 ID:', process.pid);
console.log('父进程 ID:', process.ppid);
console.log('Node 版本:', process.version);
console.log('平台:', process.platform);
console.log('架构:', process.arch);
console.log('当前工作目录:', process.cwd());
console.log('执行路径:', process.execPath);

// 命令行参数
console.log('命令行参数:', process.argv);
// node app.js arg1 arg2
// [ '/usr/bin/node', '/path/to/app.js', 'arg1', 'arg2' ]

// 环境变量
console.log('环境变量:', process.env);
console.log('NODE_ENV:', process.env.NODE_ENV);

// 退出进程
process.exit(0);      // 成功退出
process.exit(1);      // 失败退出

// 监听退出事件
process.on('exit', (code) => {
    console.log(`进程退出,退出码: ${code}`);
});

// 监听信号
process.on('SIGINT', () => {
    console.log('接收到 SIGINT 信号(Ctrl+C)');
    process.exit(0);
});

process.on('SIGTERM', () => {
    console.log('接收到 SIGTERM 信号');
    process.exit(0);
});

# 优雅退出

const express = require('express');
const app = express();

const server = app.listen(3000);

// 优雅退出
function gracefulShutdown(signal) {
    console.log(`接收到 ${signal} 信号,开始优雅退出...`);
    
    server.close(() => {
        console.log('HTTP 服务器已关闭');
        
        // 关闭数据库连接等
        // db.close();
        
        console.log('进程退出');
        process.exit(0);
    });
    
    // 强制退出(30 秒后)
    setTimeout(() => {
        console.error('强制退出');
        process.exit(1);
    }, 30000);
}

process.on('SIGTERM', () => gracefulShutdown('SIGTERM'));
process.on('SIGINT', () => gracefulShutdown('SIGINT'));

# 八、定时器高级用法

# 高精度计时

// console.time/timeEnd(毫秒精度)
console.time('operation');
for (let i = 0; i < 1e6; i++) {}
console.timeEnd('operation'); // operation: 2.345ms

// process.hrtime(纳秒精度)
const start = process.hrtime();
for (let i = 0; i < 1e6; i++) {}
const end = process.hrtime(start);
console.log(`耗时: ${end[0]}s ${end[1] / 1e6}ms`);

// process.hrtime.bigint(ES2020)
const start2 = process.hrtime.bigint();
for (let i = 0; i < 1e6; i++) {}
const end2 = process.hrtime.bigint();
console.log(`耗时: ${Number(end2 - start2) / 1e6}ms`);

# setImmediate vs process.nextTick

// setImmediate:在下一次事件循环执行
setImmediate(() => {
    console.log('setImmediate 1');
});

setImmediate(() => {
    console.log('setImmediate 2');
});

// process.nextTick:在当前阶段结束后立即执行
process.nextTick(() => {
    console.log('nextTick 1');
});

process.nextTick(() => {
    console.log('nextTick 2');
});

console.log('Sync');

// 输出:
// Sync
// nextTick 1
// nextTick 2
// setImmediate 1
// setImmediate 2

# 九、异步编程进阶

# async_hooks(异步资源追踪)

const async_hooks = require('async_hooks');

const hook = async_hooks.createHook({
    init(asyncId, type, triggerAsyncId) {
        console.log(`Init: ${type}(${asyncId}), Trigger: ${triggerAsyncId}`);
    },
    before(asyncId) {
        console.log(`Before: ${asyncId}`);
    },
    after(asyncId) {
        console.log(`After: ${asyncId}`);
    },
    destroy(asyncId) {
        console.log(`Destroy: ${asyncId}`);
    }
});

hook.enable();

setTimeout(() => {
    console.log('Timeout executed');
}, 100);

// 输出:
// Init: Timeout(2), Trigger: 1
// Before: 2
// Timeout executed
// After: 2
// Destroy: 2

# Worker Threads(工作线程)

Node.js 10.5+ 支持工作线程,用于 CPU 密集型任务:

// main.js
const { Worker } = require('worker_threads');

function runWorker(workerData) {
    return new Promise((resolve, reject) => {
        const worker = new Worker('./worker.js', { workerData });
        
        worker.on('message', resolve);
        worker.on('error', reject);
        worker.on('exit', (code) => {
            if (code !== 0) {
                reject(new Error(`工作线程退出,退出码: ${code}`));
            }
        });
    });
}

async function main() {
    const result = await runWorker({ num: 1000000 });
    console.log('结果:', result);
}

main();
// worker.js
const { parentPort, workerData } = require('worker_threads');

function heavyTask(num) {
    let result = 0;
    for (let i = 0; i < num; i++) {
        result += i;
    }
    return result;
}

const result = heavyTask(workerData.num);
parentPort.postMessage(result);

# 线程池

const { Worker } = require('worker_threads');

class WorkerPool {
    constructor(workerScript, poolSize) {
        this.workerScript = workerScript;
        this.poolSize = poolSize;
        this.workers = [];
        this.queue = [];
        
        for (let i = 0; i < poolSize; i++) {
            this.workers.push({ worker: null, available: true });
        }
    }
    
    async execute(workerData) {
        return new Promise((resolve, reject) => {
            const task = { workerData, resolve, reject };
            
            const availableWorker = this.workers.find(w => w.available);
            if (availableWorker) {
                this.runTask(availableWorker, task);
            } else {
                this.queue.push(task);
            }
        });
    }
    
    runTask(workerSlot, task) {
        workerSlot.available = false;
        
        const worker = new Worker(this.workerScript, {
            workerData: task.workerData
        });
        
        worker.on('message', (result) => {
            task.resolve(result);
            this.finishTask(workerSlot);
        });
        
        worker.on('error', (err) => {
            task.reject(err);
            this.finishTask(workerSlot);
        });
        
        workerSlot.worker = worker;
    }
    
    finishTask(workerSlot) {
        workerSlot.worker = null;
        workerSlot.available = true;
        
        if (this.queue.length > 0) {
            const nextTask = this.queue.shift();
            this.runTask(workerSlot, nextTask);
        }
    }
}

// 使用
const pool = new WorkerPool('./worker.js', 4);

async function main() {
    const tasks = [1000000, 2000000, 3000000, 4000000];
    const results = await Promise.all(
        tasks.map(num => pool.execute({ num }))
    );
    console.log('结果:', results);
}

main();

# 十、安全最佳实践

# 输入验证

const express = require('express');
const { body, validationResult } = require('express-validator');

const app = express();
app.use(express.json());

app.post('/user', [
    body('email').isEmail(),
    body('age').isInt({ min: 0, max: 150 }),
    body('name').isLength({ min: 1, max: 100 })
], (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
        return res.status(400).json({ errors: errors.array() });
    }
    
    res.json({ message: '验证通过' });
});

app.listen(3000);

# 防止 SQL 注入

// ❌ 错误:拼接 SQL
const userId = req.params.id;
const query = `SELECT * FROM users WHERE id = ${userId}`; // 危险!

// ✅ 正确:使用参数化查询
const query = 'SELECT * FROM users WHERE id = ?';
db.query(query, [userId]);

# 防止 XSS

const express = require('express');
const helmet = require('helmet');
const xss = require('xss-clean');

const app = express();

// 设置安全 HTTP 头
app.use(helmet());

// 清理用户输入
app.use(xss());

app.listen(3000);

# 速率限制

const rateLimit = require('express-rate-limit');

const limiter = rateLimit({
    windowMs: 15 * 60 * 1000, // 15 分钟
    max: 100,                 // 最多 100 个请求
    message: '请求过于频繁,请稍后再试'
});

app.use('/api/', limiter);

# 环境变量保护

// ❌ 错误:硬编码敏感信息
const apiKey = 'my-secret-api-key';

// ✅ 正确:使用环境变量
require('dotenv').config();
const apiKey = process.env.API_KEY;

if (!apiKey) {
    throw new Error('API_KEY 环境变量未设置');
}

# 十一、总结

Node.js 的高级特性是构建高性能、可扩展应用的基础:

  • 事件循环:理解六个阶段、微任务队列、定时器执行顺序
  • 流:掌握四种流类型、管道、背压处理
  • 缓冲区:处理二进制数据、字符编码
  • 子进程:exec、spawn、fork 的区别与应用
  • 集群:利用多核 CPU、负载均衡、进程间通信
  • 性能优化:缓存、连接池、压缩、避免阻塞
  • 进程管理:优雅退出、信号处理
  • 异步编程:async_hooks、Worker Threads、线程池
  • 安全实践:输入验证、防注入、速率限制

这些知识结合 Node.js快速入门 和 JavaScript高级特性详解,能够帮助你构建企业级 Node.js 应用。

祝你变得更强!

编辑 (opens new window)
#Node.js#JavaScript
上次更新: 2025/11/07
Node.js快速入门
Vue.js历代版本新特性

← Node.js快速入门 Vue.js历代版本新特性→

最近更新
01
AI编程时代的一些心得
09-11
02
Claude Code与Codex的协同工作
09-01
03
Claude Code 最佳实践(个人版)
08-01
更多文章>
Theme by Vdoing | Copyright © 2018-2025 京ICP备2021021832号-2 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式