您现在的位置是:网站首页 > 生产环境配置与调优文章详情
生产环境配置与调优
陈川
【
Node.js
】
28189人已围观
5209字
生产环境配置与调优
Express作为Node.js最流行的Web框架之一,在生产环境中需要特别关注性能、安全性和稳定性。合理的配置和调优能显著提升应用吞吐量,降低响应延迟,同时保障系统安全。
环境变量管理
生产环境必须使用环境变量存储敏感配置,避免硬编码。推荐使用dotenv
库管理环境变量:
require('dotenv').config();
const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000;
const DB_URI = process.env.MONGODB_URI;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
.env
文件示例:
PORT=8080
MONGODB_URI=mongodb://user:pass@host:port/db
NODE_ENV=production
性能优化中间件
启用Gzip压缩
使用compression
中间件减少传输数据量:
const compression = require('compression');
app.use(compression({
level: 6, // 压缩级别1-9
threshold: 10 * 1024 // 大于10KB才压缩
}));
静态资源缓存
设置长期缓存策略减少重复请求:
const expressStaticGzip = require("express-static-gzip");
app.use("/static", expressStaticGzip("public", {
enableBrotli: true,
orderPreference: ["br", "gzip"],
setHeaders: (res) => {
res.setHeader("Cache-Control", "public, max-age=31536000");
}
}));
集群模式部署
利用多核CPU启动集群:
const cluster = require('cluster');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}
} else {
const app = require('./app');
app.listen(3000);
}
日志记录优化
生产环境需要结构化日志:
const winston = require('winston');
const expressWinston = require('express-winston');
app.use(expressWinston.logger({
transports: [
new winston.transports.File({
filename: 'logs/request.log',
level: 'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.json()
)
})
],
meta: true,
msg: "HTTP {{req.method}} {{req.url}}",
expressFormat: true
}));
安全加固配置
设置安全头部
使用helmet
中间件增强安全性:
const helmet = require('helmet');
app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "trusted.cdn.com"]
}
},
hsts: {
maxAge: 63072000,
includeSubDomains: true,
preload: true
}
}));
请求频率限制
防止暴力攻击:
const rateLimit = require('express-rate-limit');
const apiLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 100,
message: 'Too many requests from this IP'
});
app.use('/api/', apiLimiter);
数据库连接优化
使用连接池提高数据库访问效率:
const { Pool } = require('pg');
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
max: 20,
idleTimeoutMillis: 30000,
connectionTimeoutMillis: 2000
});
app.get('/data', async (req, res) => {
const client = await pool.connect();
try {
const result = await client.query('SELECT * FROM large_table');
res.json(result.rows);
} finally {
client.release();
}
});
错误处理机制
生产环境需要完善的错误处理:
app.use((err, req, res, next) => {
console.error(err.stack);
if (req.accepts('json')) {
res.status(500).json({
error: 'Internal Server Error',
requestId: req.id
});
} else {
res.type('txt').send('Internal Server Error');
}
});
process.on('unhandledRejection', (reason, promise) => {
console.error('Unhandled Rejection at:', promise, 'reason:', reason);
});
process.on('uncaughtException', (err) => {
console.error('Uncaught Exception:', err);
process.exit(1);
});
性能监控与分析
集成APM工具监控应用性能:
const apm = require('elastic-apm-node').start({
serviceName: 'express-app',
serverUrl: 'http://apm-server:8200',
captureExceptions: true,
metricsInterval: '30s'
});
app.use(apm.middleware.connect());
模板引擎优化
如果使用模板引擎,启用缓存:
app.set('view engine', 'pug');
app.set('view cache', true);
app.enable('view cache');
负载均衡配置
Nginx反向代理示例配置:
upstream nodejs_backend {
server 127.0.0.1:3000;
server 127.0.0.1:3001;
keepalive 64;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://nodejs_backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
内存泄漏排查
使用heapdump
捕获内存快照:
const heapdump = require('heapdump');
setInterval(() => {
if (process.memoryUsage().heapUsed > 500 * 1024 * 1024) {
heapdump.writeSnapshot(`heap-${Date.now()}.heapsnapshot`);
}
}, 60 * 1000);
持续集成部署
.github/workflows/deploy.yml
示例:
name: Node.js CI
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Use Node.js
uses: actions/setup-node@v2
with:
node-version: '16'
- run: npm ci
- run: npm test
- run: npm run build
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Deploy to Production
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.PRODUCTION_HOST }}
username: ${{ secrets.PRODUCTION_USER }}
key: ${{ secrets.PRODUCTION_SSH_KEY }}
script: |
cd /var/www/express-app
git pull origin main
npm install --production
pm2 restart app