零停机部署策略:在更新期间保持应用程序运行

通过蓝绿、滚动和金丝雀策略实施零停机部署。涵盖数据库迁移、运行状况检查和自动回滚模式。

E
ECOSIRE Research and Development Team
|2026年3月16日4 分钟阅读749 字数|

零停机部署策略:在更新期间保持应用程序运行

计划内停机平均每分钟给企业造成 5,600 美元的成本。 然而,43% 的公司仍然在部署期间将其应用程序脱机。零停机部署并不是一种奢侈——而是一种期望。客户、搜索引擎和集成合作伙伴都会对离线(即使是短暂离线)的应用程序进行惩罚。

本指南涵盖了三种主要的零停机部署策略、保持正常运行时间的数据库迁移技术以及自动回滚机制。

要点

  • 蓝绿部署是最安全的策略:通过将流量切换回之前的版本来即时回滚
  • 数据库迁移必须向后兼容 --- 旧应用程序版本必须适用于新架构
  • 健康检查和就绪探测可防止将流量路由到尚未准备好提供服务的 Pod
  • 基于错误率监控的自动回滚将平均恢复时间缩短至 2 分钟以下

策略比较

战略复杂性回滚速度基础设施成本最适合
蓝绿色即时(秒)部署期间 2xCritical applications, infrequent deploys
滚动更新中等分钟部署期间 1.25 倍Kubernetes,频繁部署
金丝雀快(秒)部署期间 1.05 倍高流量、风险敏感
功能标志中等即时1x逐步推出功能

蓝绿部署

架构

Load Balancer
    |
    |--- [ACTIVE] Blue environment (v2.0.0) <-- receives 100% traffic
    |
    |--- [IDLE] Green environment (v2.1.0) <-- deployed, tested, waiting

部署时: 1、部署v2.1.0到空闲(绿色)环境 2. 针对绿色进行冒烟测试 3. 将负载均衡器切换为绿色 4.蓝色变为空闲(可即时回滚)

使用 Nginx 实现

# /etc/nginx/conf.d/app.conf
upstream blue {
    server 10.0.1.10:3000;
    server 10.0.1.11:3000;
}

upstream green {
    server 10.0.2.10:3000;
    server 10.0.2.11:3000;
}

# Active environment - change this during deployment
map $host $active_upstream {
    default blue;  # Change to 'green' to switch
}

server {
    listen 443 ssl;
    server_name app.example.com;

    location / {
        proxy_pass http://$active_upstream;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

部署脚本

#!/bin/bash
set -e

CURRENT=$(cat /etc/nginx/active-env)  # "blue" or "green"
TARGET=$( [ "$CURRENT" = "blue" ] && echo "green" || echo "blue" )

echo "Current: $CURRENT, deploying to: $TARGET"

# Deploy to inactive environment
ssh "deploy@$TARGET-1" "cd /opt/app && git pull && pnpm install --frozen-lockfile && pnpm build && pm2 restart all"
ssh "deploy@$TARGET-2" "cd /opt/app && git pull && pnpm install --frozen-lockfile && pnpm build && pm2 restart all"

# Wait for health checks
for i in 1 2; do
  echo "Checking $TARGET-$i health..."
  for attempt in $(seq 1 30); do
    if curl -sf "http://$TARGET-$i:3000/health" > /dev/null; then
      echo "$TARGET-$i is healthy"
      break
    fi
    sleep 2
  done
done

# Run smoke tests
pnpm test:smoke --base-url "http://$TARGET-1:3000"

# Switch traffic
sed -i "s/default $CURRENT/default $TARGET/" /etc/nginx/conf.d/app.conf
nginx -s reload
echo "$TARGET" > /etc/nginx/active-env

echo "Traffic switched to $TARGET. Rollback: change active-env back to $CURRENT"

滚动更新

滚动更新逐步替换实例,确保部分容量始终可用。

Kubernetes 滚动更新

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
spec:
  replicas: 5
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1        # Create 1 extra pod during update
      maxUnavailable: 0   # Never reduce below desired replicas
  template:
    spec:
      containers:
        - name: api
          image: registry.example.com/api:v2.1.0
          readinessProbe:
            httpGet:
              path: /health
              port: 3001
            initialDelaySeconds: 5
            periodSeconds: 5
          livenessProbe:
            httpGet:
              path: /health
              port: 3001
            initialDelaySeconds: 15
            periodSeconds: 10

使用 maxSurge: 1maxUnavailable: 0 的滚动更新过程:

  1. 使用 v2.1.0 创建 1 个新 pod(总共 6 个 pod:5 个旧 + 1 个新)
  2. Wait for new pod readiness probe to pass
  3. 终止 1 个旧 Pod(5 个 Pod:4 个旧 Pod + 1 个新 Pod)
  4. 创建另一个新 Pod(6 个 Pod:4 个旧 + 2 个新)
  5. 重复直到所有 pod 都是 v2.1.0

金丝雀部署

流量分割

# Istio VirtualService for canary routing
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: api-canary
spec:
  hosts:
    - api.example.com
  http:
    - route:
        - destination:
            host: api-stable
            port:
              number: 3001
          weight: 95
        - destination:
            host: api-canary
            port:
              number: 3001
          weight: 5

渐进式金丝雀推出

金丝雀交通持续时间成功标准
11%10 分钟错误率<0.1%,延迟<500ms
25%30 分钟错误率<0.1%,延迟<500ms
325%1小时错误率<0.5%,延迟<1s
450%2小时错误率<0.5%,延迟<1s
5100%全面推出24小时稳定

数据库迁移无需停机

零停机部署的最大挑战是数据库架构更改。旧应用程序版本必须适用于新架构,反之亦然。

扩展-收缩模式

阶段 1:扩展(部署架构更改)

-- Add new column (nullable, no default)
ALTER TABLE orders ADD COLUMN shipping_method VARCHAR(50);

旧的应用程序代码会忽略新列。新的应用程序代码写入旧列和新列。

阶段 2:迁移数据

-- Backfill existing data
UPDATE orders SET shipping_method = 'standard' WHERE shipping_method IS NULL;

阶段 3:合同(部署专门使用新列的代码)

所有应用程序实例都使用新列后:

-- Make column required
ALTER TABLE orders ALTER COLUMN shipping_method SET NOT NULL;
ALTER TABLE orders ALTER COLUMN shipping_method SET DEFAULT 'standard';

危险的迁移模式

图案风险安全替代方案
重命名列打破旧代码添加新列、迁移、删除旧列
删除栏目打破旧代码停止使用,然后投入下一个版本
添加 NOT NULL 列锁具表添加可空、回填、更改为 NOT NULL
更改列类型锁定表,中断查询添加具有新类型的新列,迁移
添加唯一索引在大桌子上锁定桌子代码0

自动回滚

基于错误率的回滚

#!/bin/bash
# post-deploy-monitor.sh

DEPLOY_TIME=$(date +%s)
MONITOR_DURATION=300  # 5 minutes
ERROR_THRESHOLD=0.02  # 2%

while [ $(($(date +%s) - DEPLOY_TIME)) -lt $MONITOR_DURATION ]; do
  ERROR_RATE=$(curl -s "http://prometheus:9090/api/v1/query?query=rate(http_requests_total{status=~'5..'}[2m])/rate(http_requests_total[2m])" | jq -r '.data.result[0].value[1]')

  if (( $(echo "$ERROR_RATE > $ERROR_THRESHOLD" | bc -l) )); then
    echo "ERROR: Rate $ERROR_RATE exceeds threshold $ERROR_THRESHOLD"
    echo "Initiating rollback..."
    kubectl rollout undo deployment/api
    exit 1
  fi

  sleep 15
done

echo "Deployment healthy for $MONITOR_DURATION seconds"

常见问题

我们应该从哪种策略开始?

从蓝绿部署开始。它实现起来最简单,提供即时回滚,并且适用于任何应用程序架构。滚动更新更适合具有许多副本的 Kubernetes 环境。金丝雀部署适用于高流量应用程序,您希望在全面部署之前使用实际流量验证更改。

我们如何在部署过程中处理长时间运行的后台作业?

使用优雅关闭。当 Pod 收到终止信号时,停止接受新作业,完成正在进行的作业(有超时),然后关闭。在 Kubernetes 中,配置 terminationGracePeriodSeconds 以留出足够的时间来完成作业。对于需要比宽限期更长的作业,请使用作业队列(Redis、RabbitMQ)在幸存的工作线程上重试失败的作业。

部署期间的 WebSocket 连接怎么样?

WebSocket 连接是长期存在的,必须小心处理。在滚动更新期间,旧 Pod 上的现有连接保持活动状态,直到 Pod 终止。客户端应该实现自动重新连接逻辑。对于蓝绿部署,将新连接切换到新环境,同时允许现有连接在超时的情况下耗尽旧环境。

我们如何测试零停机部署?

在部署期间运行负载测试。使用k6或类似工具生成持续流量,然后触发部署。检查翻转期间是否有任何错误、延迟增加或连接丢失。请参阅我们的负载测试指南 了解实施细节。


接下来会发生什么

零停机部署是频繁、自信发布的先决条件。将其与 CI/CD 自动化 相结合以实现完整的部署管道,并与 监控 相结合以进行部署后验证。

联系 ECOSIRE 获取部署策略咨询,或浏览我们的 DevOps 指南 获取完整的基础设施路线图。


由 ECOSIRE 发布——帮助企业无中断部署。

E

作者

ECOSIRE Research and Development Team

在 ECOSIRE 构建企业级数字产品。分享关于 Odoo 集成、电商自动化和 AI 驱动商业解决方案的洞见。

通过 WhatsApp 聊天