生产环境Node.js集群部署完整指南
随着业务规模的扩大,单机Node.js部署已无法满足高可用和高并发的需求。本文将详细介绍如何从零构建企业级Node.js集群架构,涵盖环境配置、进程管理、负载均衡、性能监控和压力测试等核心环节。
一、多版本Node.js环境管理
企业级应用往往需要兼容不同项目对Node.js版本的差异化需求。通过nvm(Node Version Manager)实现版本隔离是最佳实践。
1.1 安装nvm
# 安装nvm(Linux/macOS)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
# 验证安装
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
nvm --version
1.2 安装多版本Node.js
# 安装LTS版本
nvm install --lts
nvm install 18.20.0
nvm install 20.12.0
# 设置默认版本
nvm alias default 20.12.0
# 查看已安装版本
nvm ls
# 切换版本
nvm use 18.20.0
二、PM2进程管理器配置
PM2是Node.js生产环境的首选进程管理工具,提供进程守护、负载均衡、日志管理等企业级功能。
2.1 全局安装PM2
npm install -g pm2
# 验证安装
pm2 --version
2.2 配置文件示例(ecosystem.config.js)
module.exports = {
apps: [{
name: 'api-service',
script: './src/index.js',
instances: 'max',
exec_mode: 'cluster',
watch: false,
max_memory_restart: '1G',
env: {
NODE_ENV: 'production',
PORT: 3000
},
error_file: '/var/log/pm2/api-error.log',
out_file: '/var/log/pm2/api-out.log',
log_date_format: 'YYYY-MM-DD HH:mm:ss',
autorestart: true,
max_restarts: 10,
min_uptime: '10s',
listen_timeout: 8000,
kill_timeout: 5000,
merge_logs: true
}]
};
2.3 常用管理命令
# 启动应用
pm2 start ecosystem.config.js
# 查看进程状态
pm2 list
pm2 monit
# 重启/重载
pm2 restart api-service
pm2 reload api-service
# 停止/删除
pm2 stop api-service
pm2 delete api-service
# 日志管理
pm2 logs api-service --lines 100
pm2 flush # 清空日志
三、Nginx负载均衡配置
在多服务器集群环境中,Nginx作为反向代理承担负载均衡职责。
3.1 upstream配置
upstream node_cluster {
least_conn; # 最少连接数算法
server 10.0.0.11:3000 weight=5;
server 10.0.0.12:3000 weight=5;
server 10.0.0.13:3000 weight=3;
keepalive 32; # 长连接
}
server {
listen 443 ssl http2;
server_name api.example.com;
ssl_certificate /etc/ssl/certs/server.crt;
ssl_certificate_key /etc/ssl/private/server.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
location / {
proxy_pass http://node_cluster;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache_bypass $http_upgrade;
proxy_connect_timeout 30s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
}
# 健康检查
location /health {
proxy_pass http://node_cluster/health;
access_log off;
}
}
四、性能监控体系
生产环境必须建立完善的监控体系,确保服务稳定运行。
4.1 PM2 Plus监控
# 启用PM2 Plus云监控
pm2 link your-secret-key your-public-key
# 或使用本地仪表板
pm2 plus
4.2 自定义监控脚本
// health-check.js
const os = require('os');
function getSystemMetrics() {
const cpus = os.cpus();
const totalMem = os.totalmem();
const freeMem = os.freemem();
const cpuUsage = cpus.reduce((acc, cpu) => {
const total = Object.values(cpu.times).reduce((a, b) => a + b, 0);
const idle = cpu.times.idle;
return acc + ((total - idle) / total * 100);
}, 0) / cpus.length;
return {
cpu: cpuUsage.toFixed(2),
memory: ((totalMem - freeMem) / totalMem * 100).toFixed(2),
timestamp: Date.now()
};
}
module.exports = { getSystemMetrics };
4.3 告警脚本示例
// alert.js - 资源告警监控
const { getSystemMetrics } = require('./health-check');
function checkThresholds() {
const metrics = getSystemMetrics();
if (metrics.cpu > 80) {
console.log(`[ALERT] CPU使用率过高: ${metrics.cpu}%`);
// 发送告警通知
}
if (metrics.memory > 85) {
console.log(`[ALERT] 内存使用率过高: ${metrics.memory}%`);
}
return metrics;
}
setInterval(checkThresholds, 60000); // 每分钟检查
checkThresholds();
五、压力测试方案
上线前的压力测试是验证系统性能的关键环节。
5.1 使用wrk进行基础压测
# 安装wrk
brew install wrk # macOS
# Ubuntu: sudo apt install wrk
# 基础压测
wrk -t12 -c400 -d30s http://localhost:3000/api
# 参数说明:
# -t12: 12个线程
# -c400: 400个连接
# -d30s: 持续30秒
5.2 高级压测脚本
// load-test.js - 自定义压测脚本
const http = require('http');
const options = {
hostname: 'localhost',
port: 3000,
path: '/api/users',
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
};
function makeRequest() {
return new Promise((resolve, reject) => {
const start = Date.now();
const req = http.request(options, (res) => {
let data = '';
res.on('data', chunk => data += chunk);
res.on('end', () => {
resolve({
status: res.statusCode,
latency: Date.now() - start,
timestamp: new Date().toISOString()
});
});
});
req.on('error', reject);
req.setTimeout(5000, () => {
req.destroy();
reject(new Error('Request timeout'));
});
req.end();
});
}
async function runLoadTest(duration, concurrency) {
const results = [];
const endTime = Date.now() + duration;
while (Date.now() < endTime) {
const promises = Array(concurrency).fill().map(() =>
makeRequest().catch(err => ({ error: err.message }))
);
const batchResults = await Promise.all(promises);
results.push(...batchResults);
await new Promise(r => setTimeout(r, 100)); // 100ms间隔
}
const successCount = results.filter(r => r.status === 200).length;
const errors = results.filter(r => r.error).length;
const latencies = results.filter(r => r.latency).map(r => r.latency);
console.log(`总请求数: ${results.length}`);
console.log(`成功: ${successCount}, 失败: ${errors}`);
console.log(`平均延迟: ${(latencies.reduce((a,b)=>a+b,0)/latencies.length).toFixed(2)}ms`);
console.log(`最大延迟: ${Math.max(...latencies)}ms`);
console.log(`最小延迟: ${Math.min(...latencies)}ms`);
}
// 运行60秒压测,并发50
runLoadTest(60000, 50);
5.3 测试报告模板
| 指标 | 预期值 | 实际值 | 状态 |
|---|---|---|---|
| QPS | >1000 | 待测试 | - |
| 平均响应时间 | <200ms | 待测试 | - |
| P99延迟 | <500ms | 待测试 | - |
| 错误率 | <0.1% | 待测试 | - |
| CPU峰值 | <80% | 待测试 | - |
总结
本文详细介绍了企业级Node.js集群部署的完整方案,涵盖版本管理、进程管理、负载均衡、监控告警和压力测试五大核心模块。通过合理配置这些组件,可以构建出支撑高并发的生产级Node.js服务架构。建议在正式部署前在测试环境充分验证各环节配置,确保系统稳定性和可靠性。