生产环境运维
What — 是什么
生产环境运维是保障 Node.js 服务稳定运行的工程实践,涵盖部署策略、回滚、限流降级、告警和灾备。
核心概念:
- 部署策略:滚动更新(零停机)、蓝绿部署(两套环境切换)、金丝雀发布(逐步放量)
- 回滚:部署失败后恢复到上一稳定版本
- 限流降级:QPS 超限时拒绝部分请求,保护核心功能
- 熔断:下游服务不可用时快速失败,防止级联故障
- 告警:异常指标(错误率/延迟/内存)触发通知
- SLA:服务等级协议,如 99.9% 可用性 = 月停机 < 43 分钟
- 灾备:多可用区/多地域部署,RPO/RTO 指标
关键特性:
- K8s 滚动更新默认零停机
- 蓝绿部署切换 DNS/负载均衡即可
- 限流用令牌桶/漏桶算法
- 熔断器有 Closed/Open/Half-Open 三态
Why — 为什么
适用场景:
- 所有生产级 Node.js 服务
- 需要 99.9%+ 可用性的核心业务
- 多团队协作的大型项目
How — 怎么用
代码示例
// 限流中间件
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({ windowMs: 60000, max: 100, standardHeaders: true });
app.use('/api/', limiter);
// 熔断器(opossum)
const CircuitBreaker = require('opossum');
const breaker = new CircuitBreaker(externalApiCall, {
timeout: 3000, errorThresholdPercentage: 50, resetTimeout: 30000
});
breaker.fallback(() => ({ data: null, degraded: true }));
breaker.on('open', () => logger.warn('Circuit breaker opened'));
// 降级:部分数据不可用时返回可用数据
app.get('/api/home', async (req, res) => {
const [user, feed, recommendations] = await Promise.allSettled([
getUser(req.user.id),
getFeed(req.user.id),
getRecommendations(req.user.id)
]);
res.json({
user: user.status === 'fulfilled' ? user.value : null,
feed: feed.status === 'fulfilled' ? feed.value : [],
recommendations: recommendations.status === 'fulfilled' ? recommendations.value : [],
degraded: [user, feed, recommendations].some(r => r.status === 'rejected')
});
});
// 优雅关闭
process.on('SIGTERM', () => {
server.close(() => process.exit(0));
setTimeout(() => process.exit(1), 10000);
});
常见问题与踩坑
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 部署后服务不可用 | 新版本有 bug | 立即回滚到上一版本 |
| 级联故障 | 下游服务超时拖垮上游 | 熔断器 + 超时设置 |
| 内存持续增长 | 泄漏未及时发现 | 内存告警 + 自动重启 |
最佳实践
- 部署前在 staging 环境验证
- K8s 使用滚动更新 + readiness 探针
- 所有的外部调用设超时 + 熔断
- 核心指标设告警(错误率/延迟/内存)
- 实现降级策略保证核心功能可用
面试题
Q1: 蓝绿部署和金丝雀发布的区别?
蓝绿部署:维护两套完全相同的环境(蓝/绿),当前生产在蓝,部署新版本到绿,验证后切换流量到绿。切换瞬间完成,回滚也只需切回蓝。缺点:需要双倍资源。金丝雀发布:新旧版本同时运行,逐步将流量从旧版本切换到新版本(5%→10%→50%→100%)。每个阶段观察指标,异常则停止并回滚。优点:风险可控,不需要双倍资源。适合大型服务。
Q2: 如何设计高可用 Node.js 服务?
多层保障:① 多实例 + 负载均衡——Cluster 模式/K8s 多 Pod,单实例崩溃不影响服务;② 多可用区——部署在不同机架/机房,单机房故障不影响;③ 健康检查 + 自动重启——K8s liveness/readiness 探针;④ 限流 + 熔断——保护服务不被突发流量打垮;⑤ 数据库主从 + 读写分离——数据库单点消除;⑥ 缓存降级——数据库不可用时返回缓存数据;⑦ 监控告警——异常第一时间发现和响应。目标:99.9% 可用性 = 月停机 < 43 分钟。
相关链接: