Chuyển đến nội dung chính

第 10 課:叢集模組和負載平衡

叢集模組,fork(),迴圈。 PM2進程管理器,優雅關機。黏性會議,共享狀態挑戰。零停機部署,滾動重啟。

💻 程式設計 — 第 10 課 第 10 課:叢集模組和負載平衡

Node.js 核心:從基礎到高級

第 3 部分:並發與網絡

亞洲開發網

1. 集群模組

import cluster from 'node:cluster'
import { createServer } from 'node:http'
import os from 'node:os'

const numCPUs = os.cpus().length

if (cluster.isPrimary) {
  console.log(`Primary ${process.pid} is running`)

  // Fork workers
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork()
  }

  cluster.on('exit', (worker, code, signal) => {
    console.log(`Worker ${worker.process.pid} died (${signal || code})`)
    cluster.fork() // Auto-restart
  })
} else {
  const server = createServer((req, res) => {
    res.writeHead(200)
    res.end(`Worker ${process.pid}\n`)
  })

  server.listen(3000)
  console.log(`Worker ${process.pid} started`)
}

2. 正常關機

if (cluster.isPrimary) {
  function shutdown() {
    console.log('Shutting down cluster...')
    for (const id in cluster.workers) {
      cluster.workers[id]?.send('shutdown')
    }
    setTimeout(() => process.exit(0), 10000) // Force exit after 10s
  }

  process.on('SIGTERM', shutdown)
  process.on('SIGINT', shutdown)
} else {
  const server = createServer(handler)
  server.listen(3000)

  process.on('message', (msg) => {
    if (msg === 'shutdown') {
      server.close(() => {
        console.log(`Worker ${process.pid} closed gracefully`)
        process.exit(0)
      })
    }
  })
}

3.PM2流程管理器

// ecosystem.config.cjs
module.exports = {
  apps: [{
    name: 'api-server',
    script: 'dist/app.js',
    instances: 'max',        // Số CPU cores
    exec_mode: 'cluster',
    max_memory_restart: '1G',
    env_production: {
      NODE_ENV: 'production',
      PORT: 3000,
    },
    // Logs
    error_file: 'logs/err.log',
    out_file: 'logs/out.log',
    merge_logs: true,
    log_date_format: 'YYYY-MM-DD HH:mm:ss',
  }],
}
# PM2 commands
pm2 start ecosystem.config.cjs --env production
pm2 reload api-server       # Zero-downtime reload
pm2 scale api-server +2     # Thêm 2 instances
pm2 monit                   # Monitor dashboard
pm2 logs api-server --lines 50
pm2 save && pm2 startup     # Auto-start on boot

4. 零停機部署

#!/bin/bash
# deploy.sh
git pull origin main
pnpm install --frozen-lockfile
pnpm build
pm2 reload ecosystem.config.cjs --env production
# PM2 reload từng worker 1, đảm bảo luôn có worker handling requests

5. 粘性會話

// Khi dùng WebSocket hoặc session, cần sticky sessions
// Dùng nginx upstream hoặc PM2 sticky cluster

// Với nginx:
// upstream app {
//   ip_hash;  # Sticky sessions
//   server 127.0.0.1:3001;
//   server 127.0.0.1:3002;
// }

下一篇: TCP、UDP 和 WebSocket - 淨,dgram,ws。