前置知识: JavaScript

Node.js 高级特性与性能优化

00:00
4 min Advanced 2026/5/3

异步编程模式、流处理、集群与 Worker、性能调优与安全实践。

1. Node.js 高级特性

1.1 异步编程进阶

1.1.1 Async/Await 最佳实践

// 串行执行
async function serialExecution() {
  const result1 = await fetchData('url1');
  const result2 = await fetchData('url2');
  return { result1, result2 };
}
// 并行执行
async function parallelExecution() {
  const [result1, result2] = await Promise.all([fetchData('url1'), fetchData('url2')]);
  return { result1, result2 };
}
// 带超时的并行执行
async function parallelWithTimeout() {
  try {
    const [result1, result2] = await Promise.all([
      Promise.race([
        fetchData('url1'),
        new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), 5000)),
      ]),
      fetchData('url2'),
    ]);
    return { result1, result2 };
  } catch (error) {
    console.error('Error:', error);
    return { error: error.message };
  }
}

1.1.2 事件循环深入理解

// 事件循环示例
console.log('Start');
setTimeout(() => {
  console.log('Timeout');
}, 0);
Promise.resolve().then(() => {
  console.log('Promise');
});
console.log('End');
// 输出顺序: Start -> End -> Promise -> Timeout

1.2 流 (Streams)

1.2.1 可读流

const fs = require('fs');
// 创建可读流
const readableStream = fs.createReadStream('large-file.txt');
// 监听数据事件
readableStream.on('data', (chunk) => {
  console.log(`Received ${chunk.length} bytes of data`);
});
// 监听结束事件
readableStream.on('end', () => {
  console.log('End of file');
});
// 监听错误事件
readableStream.on('error', (error) => {
  console.error('Error:', error);
});

1.2.2 可写流

const fs = require('fs');
// 创建可写流
const writableStream = fs.createWriteStream('output.txt');
// 写入数据
writableStream.write('Hello, ');
writableStream.write('Node.js Streams!');
// 结束写入
writableStream.end();
// 监听完成事件
writableStream.on('finish', () => {
  console.log('Write completed');
});

1.2.3 管道流

const fs = require('fs');
const zlib = require('zlib');
// 创建可读流
const readableStream = fs.createReadStream('large-file.txt');
// 创建压缩流
const gzipStream = zlib.createGzip();
// 创建可写流
const writableStream = fs.createWriteStream('large-file.txt.gz');
// 使用管道连接流
readableStream.pipe(gzipStream).pipe(writableStream);
// 监听完成事件
writableStream.on('finish', () => {
  console.log('File compressed successfully');
});

1.3 集群 (Cluster)

const cluster = require('cluster');
const http = require('http');
const os = require('os');
if (cluster.isMaster) {
  console.log(`Master process ${process.pid} is running`);
  // 创建工作进程
  const numCPUs = os.cpus().length;
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }
  // 监听工作进程退出
  cluster.on('exit', (worker) => {
    console.log(`Worker ${worker.process.pid} died`);
    // 重启工作进程
    cluster.fork();
  });
} else {
  // 工作进程创建服务器
  http
    .createServer((req, res) => {
      res.writeHead(200);
      res.end('Hello from worker ' + process.pid);
    })
    .listen(8080);
  console.log(`Worker ${process.pid} started`);
}

1.4 子进程 (Child Process)

const { spawn, exec, fork } = require('child_process');
// 使用 spawn
const ls = spawn('ls', ['-la']);
ls.stdout.on('data', (data) => {
  console.log(`stdout: ${data}`);
});
ls.stderr.on('data', (data) => {
  console.error(`stderr: ${data}`);
});
ls.on('close', (code) => {
  console.log(`child process exited with code ${code}`);
});
// 使用 exec
exec('ls -la', (error, stdout, stderr) => {
  if (error) {
    console.error(`error: ${error.message}`);
    return;
  }
  if (stderr) {
    console.error(`stderr: ${stderr}`);
    return;
  }
  console.log(`stdout: ${stdout}`);
});
// 使用 fork
const child = fork('./child.js');
child.on('message', (message) => {
  console.log('Received from child:', message);
});
child.send({ hello: 'world' });

2. 性能优化

2.1 代码优化

2.1.1 内存管理

// 避免内存泄漏
function createClosure() {
  const largeArray = new Array(1000000).fill('data');
  return function () {
    console.log('Closure created');
    // 注意:这里没有引用 largeArray,所以它可以被垃圾回收
  };
}
// 正确处理事件监听器
class EventEmitter {
  constructor() {
    this.listeners = [];
  }
  on(event, listener) {
    this.listeners.push(listener);
    return () => {
      this.listeners = this.listeners.filter((l) => l !== listener);
    };
  }
}
// 使用 WeakMap 存储临时数据
const cache = new WeakMap();
function processObject(obj) {
  if (cache.has(obj)) {
    return cache.get(obj);
  }
  const result = expensiveOperation(obj);
  cache.set(obj, result);
  return result;
}

2.1.2 异步操作优化

// 批量处理
async function batchProcess(items, batchSize = 10) {
  const results = [];
  for (let i = 0; i < items.length; i += batchSize) {
    const batch = items.slice(i, i + batchSize);
    const batchResults = await Promise.all(batch.map(processItem));
    results.push(...batchResults);
  }
  return results;
}
// 限流
class RateLimiter {
  constructor(maxRequests, windowMs) {
    this.maxRequests = maxRequests;
    this.windowMs = windowMs;
    this.requests = [];
  }
  async limit() {
    const now = Date.now();
    // 移除过期的请求
    this.requests = this.requests.filter((time) => now - time < this.windowMs);
    if (this.requests.length >= this.maxRequests) {
      // 等待直到有可用的请求名额
      const oldestRequest = this.requests[0];
      const waitTime = this.windowMs - (now - oldestRequest);
      await new Promise((resolve) => setTimeout(resolve, waitTime));
    }
    this.requests.push(Date.now());
  }
}

2.2 网络优化

2.2.1 HTTP/2

 const http2 = require('http2');
 const fs = require('fs');
 // 创建 HTTP/2 服务器
 const server = http2.createSecureServer({
  key: fs.readFileSync('server.key'),
  cert: fs.readFileSync('server.cert')
 }
 server.on('stream', (stream, headers) => {
  stream.respond({
  ':status': 200,
  'content-type': 'text/html'
  });
  stream.end('<h1>Hello HTTP/2!</h1>');
 }
 server.listen(8443);

2.2.2 连接池

 const mysql = require('mysql2');
 // 创建连接池
 const pool = mysql.createPool({
  host: 'localhost',
  user: 'root',
  password: 'password',
  database: 'mydb',
  waitForConnections: true,
  connectionLimit: 10,
  queueLimit: 0
 }
 // 使用连接池
 async function query(sql, params) {
  return new Promise((resolve, reject) => {
  pool.query(sql, params, (error, results) => {
  if (error) {
  reject(error);
  } else {
  resolve(results);
  }
  });
  });
 }
 // 关闭连接池
 function closePool() {
  pool.end();
 }

2.3 缓存策略

2.3.1 内存缓存

class MemoryCache {
  constructor() {
    this.cache = new Map();
  }
  set(key, value, ttl = 3600000) {
    // 默认 1 小时
    const item = {
      value,
      expiry: Date.now() + ttl,
    };
    this.cache.set(key, item);
    // 设置过期清理
    setTimeout(() => {
      if (this.cache.has(key)) {
        const cachedItem = this.cache.get(key);
        if (cachedItem.expiry < Date.now()) {
          this.cache.delete(key);
        }
      }
    }, ttl);
  }
  get(key) {
    if (!this.cache.has(key)) {
      return null;
    }
    const item = this.cache.get(key);
    if (item.expiry < Date.now()) {
      this.cache.delete(key);
      return null;
    }
    return item.value;
  }
  delete(key) {
    this.cache.delete(key);
  }
  clear() {
    this.cache.clear();
  }
}
// 使用示例
const cache = new MemoryCache();
cache.set('user:1', { id: 1, name: 'John' });
const user = cache.get('user:1');

2.3.2 Redis 缓存

 const redis = require('redis');
 // 创建 Redis 客户端
 const client = redis.createClient({
  url: 'redis://localhost:6379'
 }
 client.connect();
 // 设置缓存
 async function setCache(key, value, ttl = 3600) {
  try {
  await client.set(key, JSON.stringify(value), {
  EX: ttl
  });
  } catch (error) {
  console.error('Redis set error:', error);
  }
 }
 // 获取缓存
 async function getCache(key) {
  try {
  const value = await client.get(key);
  return value ? JSON.parse(value) : null;
  } catch (error) {
  console.error('Redis get error:', error);
  return null;
  }
 }
 // 删除缓存
 async function deleteCache(key) {
  try {
  await client.del(key);
  } catch (error) {
  console.error('Redis delete error:', error);
  }
 }

3. 安全最佳实践

3.1 输入验证

 const Joi = require('joi');
 // 定义验证模式
 const userSchema = Joi.object({
  username: Joi.string()
  .alphanum()
  .min(3)
  .max(30)
  .required(),
  email: Joi.string()
  .email({ minDomainSegments: 2, tlds: { allow: ['com', 'net', 'org'] } })
  .required(),
  password: Joi.string()
  .pattern(new RegExp('^[a-zA-Z0-9]{3,30}$'))
  .required()
 }
 // 验证输入
 async function validateUser(user) {
  try {
  const value = await userSchema.validateAsync(user);
  return { valid: true, data: value };
  } catch (error) {
  return { valid: false, error: error.details[0].message };
  }
 }

3.2 防止注入攻击

 const mysql = require('mysql2');
 // 使用参数化查询防止 SQL 注入
 async function getUserById(id) {
  const sql = 'SELECT * FROM users WHERE id = ?';
  const [rows] = await pool.execute(sql, [id]);
  return rows[0];
 }
 // 使用 ORM 框架
 const Sequelize = require('sequelize');
 const sequelize = new Sequelize('database', 'username', 'password', {
  host: 'localhost',
  dialect: 'mysql'
 }
 const User = sequelize.define('User', {
  id: {
  type: Sequelize.INTEGER,
  primaryKey: true,
  autoIncrement:
  },
  username: Sequelize.STRING,
  email: Sequelize.STRING
 }
 // 安全查询
 async function findUser(id) {
  return await User.findByPk(id);
 }

3.3 身份验证与授权

const jwt = require('jsonwebtoken');
// 生成 JWT
function generateToken(user) {
  return jwt.sign({ id: user.id, username: user.username }, process.env.JWT_SECRET, {
    expiresIn: '1h',
  });
}
// 验证 JWT
function verifyToken(token) {
  try {
    return jwt.verify(token, process.env.JWT_SECRET);
  } catch (error) {
    return null;
  }
}
// 中间件验证
function authenticateToken(req, res, next) {
  const authHeader = req.headers['authorization'];
  const token = authHeader && authHeader.split(' ')[1];
  if (!token) {
    return res.status(401).json({ message: 'Access token required' });
  }
  const user = verifyToken(token);
  if (!user) {
    return res.status(403).json({ message: 'Invalid or expired token' });
  }
  req.user = user;
  next();
}

4. 测试与调试

4.1 单元测试

const assert = require('assert');
const { describe, it } = require('mocha');
function sum(a, b) {
  return a + b;
}
describe('sum function', () => {
  it('should return the sum of two numbers', () => {
    assert.strictEqual(sum(1, 2), 3);
    assert.strictEqual(sum(-1, 1), 0);
    assert.strictEqual(sum(0, 0), 0);
  });
});

4.2 性能分析

const { performance } = require('perf_hooks');
function fibonacci(n) {
  if (n <= 1) return n;
  return fibonacci(n - 1) + fibonacci(n - 2);
}
// 性能分析
const start = performance.now();
const result = fibonacci(30);
const end = performance.now();
console.log(`Fibonacci(30) = ${result}`);
console.log(`Execution time: ${end - start}ms`);
// 使用 clinic 进行更详细的分析
// npm install -g clinic
// clinic doctor -- node app.js

5. 部署与监控

5.1 容器化部署

Dockerfile

 from node:16-alpine
 WORKDIR /app
 COPY package*.json ./
 RUN npm install --production
 COPY . .
 EXPOSE 3000
 CMD [ "node", "app.js" ]

docker-compose.yml

 version: '3'
 services:
  app:
  build: .
  ports:
  - "3000:3000"
  environment:
  - NODE_ENV=production
  - DATABASE_URL=mysql://db:3306/mydb
  depends_on:
  - db
  db:
  image: mysql:5.7
  environment:
  - MYSQL_ROOT_PASSWORD=password
  - MYSQL_DATABASE=mydb
  volumes:
  - mysql-data:/var/lib/mysql
 volumes:
  mysql-data:

5.2 监控

 const prometheus = require('prom-client');
 // 创建指标
 const httpRequestCounter = new prometheus.Counter({
  name: 'http_requests_total',
  help: 'Total number of HTTP requests',
  labelNames: ['method', 'route', 'status']
 }
 const httpRequestDuration = new prometheus.Histogram({
  name: 'http_request_duration_seconds',
  help: 'HTTP request duration in seconds',
  labelNames: ['method', 'route'],
  buckets: [0.1, 0.5, 1, 2, 5]
 }
 // 中间件
 function prometheusMiddleware(req, res, next) {
  const start = Date.now();
  res.on('finish', () => {
  const duration = (Date.now() - start) / 1000;
  httpRequestCounter.inc({
  method: req.method,
  route: req.path,
  status: res.statusCode
  });
  httpRequestDuration.observe({
  method: req.method,
  route: req.path
  }, duration);
  });
  next();
 }
 // 暴露指标端点
 app.get('/metrics', async (req, res) => {
  res.set('Content-Type', prometheus.register.contentType);
  res.end(await prometheus.register.metrics());
 }

6. 项目实战

6.1 高性能 API 服务器

const express = require('express');
const cluster = require('cluster');
const os = require('os');
const Redis = require('ioredis');
if (cluster.isMaster) {
  // 启动工作进程
  const numCPUs = os.cpus().length;
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }
} else {
  const app = express();
  const redis = new Redis();
  // 中间件
  app.use(express.json());
  app.use(prometheusMiddleware);
  // 缓存中间件
  async function cacheMiddleware(req, res, next) {
    const key = `cache:${req.path}`;
    const cached = await redis.get(key);
    if (cached) {
      return res.json(JSON.parse(cached));
    }
    // 重写 res.json 方法来缓存响应
    const originalJson = res.json;
    res.json = function (data) {
      redis.set(key, JSON.stringify(data), 'EX', 300); // 5分钟缓存
      return originalJson.call(this, data);
    };
    next();
  }
  // 路由
  app.get('/api/users', cacheMiddleware, async (req, res) => {
    // 模拟数据库查询
    const users = await db.query('SELECT * FROM users');
    res.json(users);
  });
  // 启动服务器
  app.listen(3000, () => {
    console.log(`Worker ${process.pid} listening on port 3000`);
  });
}

7. 常见问题与解决方案

7.1 内存泄漏

问题:Node.js 应用内存使用持续增长 解决方案

  • 使用 node --inspect 启动应用,在 Chrome DevTools 中分析内存
  • 检查事件监听器是否正确清理
  • 避免在循环中创建闭包
  • 使用 process.memoryUsage() 监控内存使用

7.2 性能瓶颈

问题:应用响应缓慢 解决方案

  • 使用 clinic 分析性能瓶颈
  • 优化数据查询,添加索引
  • 使用缓存减少重复计算
  • 采用异步并行处理

7.3 错误处理

问题:未处理Promise 拒绝 解决方案

  • 使用 process.on('unhandledRejection', ...) 捕获处理Promise 拒绝
  • 在所有 async 函数中使用 try/catch
  • 使用错误处理中间件

8. 工具与生态

8.1 开发工具

  • Nodemon:自动重启开发服务器
  • ESLint代码质量检查
  • Prettier:代码式化
  • Jest测试框架
  • Clinic性能分析工具

8.2 框架

  • Express轻量级 Web 框架
  • Koa:Express 团队开发下一代框架
  • NestJS:基于 TypeScript企业级框架
  • Fastify性能 Web 框架

8.3 数据库 ORM

  • Sequelize支持多种数据库的 ORM
  • Prisma:现代数据库工具
  • Mongoose:MongoDB ODM
  • TypeORMTypeScript ORM

9. 延伸阅读

知识检测

学习进度

-- 已学文档
--% 知识覆盖率

学习推荐

专注模式