生产环境运维

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 分钟。


相关链接: