ASP.NET Core 应用的零停机部署策略 - 详解

上线新版本时,最怕什么?  不是代码没测好,而是——用户访问时看到“503 服务不可用”或页面直接白屏。这不仅是体验问题,更是业务损失。零停机部署(Zero Downtime Deployment),就是让你在发布新版本时,用户完全无感 —— 页面不卡、接口不断、会话不丢。

本文将手把手教你:
如何在 IIS + Windows Server 环境下,实现真正的“零停机”部署,  并结合 Jenkins 或 GitHub Actions 实现自动化发布。


2. 为什么零停机部署如此重要?

想象一下:

你正在给一个银行系统升级,部署过程需要 2 分钟。在这 2 分钟里:

  • IIS 应用池重启 → 所有请求挂起

  • 用户点击“提交订单” → 返回 503

  • 客服电话被打爆:“你们系统又崩了?”

听起来夸张?但这就是现实。

✅ 零停机部署能确保:

  • 不出现 503 错误

  • 用户会话不中断

  • 出问题能秒回滚

  • 真正实现“持续交付”


3. 零停机的核心理念

要实现零停机,靠的是三个关键:

  • 多实例并行:旧版和新版同时跑

  • 流量切换:通过负载均衡或代理,灵活引导流量

  • 原子级切换:新版本验证通过后,一次性切流,不拖泥带水

在 IIS 环境下,常用方式有:

  • 蓝绿部署(Blue-Green)→ 最经典、最安全

  • 滚动更新(Rolling Update)→ 多台服务器交替更新

  • 部署插槽(Azure App Service)→ 云原生方案

  • 负载均衡器(ARR、Nginx、硬件 LB)→ 控制流量入口


4. 技术流程图(一句话看懂)

开发者提交代码
       ↓
CI/CD 自动构建 & 测试
       ↓
发布到 Green 站点(预发布环境)
       ↓
健康检查 → 成功?
       ↓
是 → 切换流量到 Green
       ↓
监控运行状态 → 正常?
       ↓
是 → 蓝站下线;否 → 立即回滚到 Blue

✅ 核心思想:先上新,再切流,最后下旧


5. 实现步骤详解(以 Jenkins + IIS 为例)

Step 1:准备 IIS 的蓝绿站点

你需要两个 IIS 站点:

  • myapp-blue → 当前生产版本

  • myapp-green → 即将上线的新版本

它们指向不同的物理目录:

C:\inetpub\wwwroot\myapp-blue
C:\inetpub\wwwroot\myapp-green

要求:

  • 使用相同的应用程序池(避免资源竞争)

  • 绑定相同的域名(同机部署可用不同端口,比如 8080 和 8081)

  • 数据库和配置文件保持一致(除版本差异外)


Step 2:构建并发布 ASP.NET Core 应用

在 Jenkins 中执行:

dotnet clean
dotnet restore
dotnet build --configuration Release
dotnet publish -c Release -o ./publish

生成可部署的发布包。

Step 3:部署到 Green 环境

将发布包复制到 Green 目录:

Copy-Item -Path "C:\Jenkins\workspace\MyApp\publish\*" `
          -Destination "C:\inetpub\wwwroot\myapp-green" `
          -Recurse -Force

然后仅重启 Green 站点:

Restart-WebAppPool "MyAppPool"
Start-Website "myapp-green"

⚠️ 注意:不要重启整个 IIS,只重启目标站点!


Step 4:健康检查(Health Check)

在你的应用中,定义一个健康检查端点:

app.MapGet("/health", () => Results.Ok("Healthy"));

然后在 Jenkins 中执行健康检查:

curl http://localhost:8081/health

如果返回 "Healthy",说明新版本正常运行。


Step 5:流量切换(Blue → Green)

你可以通过以下方式切换:

✅ 方式 1:DNS 切换(简单但慢)
修改 DNS 记录,让域名指向 Green 站点(适合多机部署)

✅ 方式 2:IIS ARR 负载均衡
修改 ARR 规则,把所有流量导向 Green:


  
  

✅ 方式 3:Jenkins 自动化脚本

Stop-Website 'myapp-blue'
Start-Website 'myapp-green'

这样用户访问将无缝切换到新版本。


Step 6:监控与回滚

上线后,立即监控:

  • 响应时间

  • 错误率

  • CPU/内存使用率

如果发现异常,立即回滚:

Stop-Website 'myapp-green'
Start-Website 'myapp-blue'

并通知团队排查。


6. Jenkinsfile 示例

以下是一个简化版 Jenkinsfile,展示完整部署流程:

pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                bat 'dotnet clean'
                bat 'dotnet restore'
                bat 'dotnet publish -c Release -o publish'
            }
        }
        stage('Deploy to Green') {
            steps {
                powershell '''
                Copy-Item -Path "publish/*" -Destination "C:\\inetpub\\wwwroot\\myapp-green" -Recurse -Force
                Restart-WebAppPool "MyAppPool"
                Start-Website "myapp-green"
                '''
            }
        }
        stage('Health Check') {
            steps {
                script {
                    def response = bat(script:'curl http://localhost:8081/health', returnStdout:true).trim()
                    if (!response.contains("Healthy")) {
                        error("Health check failed for Green site")
                    }
                }
            }
        }
        stage('Switch Traffic') {
            steps {
                powershell '''
                Stop-Website "myapp-blue"
                Start-Website "myapp-green"
                '''
            }
        }
    }
}

7. ASP.NET Core 平滑重启配置

为了防止应用池重启时请求中断,可配置优雅关闭:

builder.WebHost.ConfigureKestrel(options =>
{
    options.AddServerHeader = false;
    options.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(2);
});
app.Lifetime.ApplicationStopping.Register(() =>
{
    Console.WriteLine("App is shutting down gracefully...");
});

这样,正在处理的请求会在应用关闭前完成,避免“半路断掉”。


8. 部署后监控

上线后,必须监控:

  • Application Insights 或 ELK(Elastic Stack)

  • 跟踪响应时间、错误率、CPU/内存使用率

  • 保留 Blue 环境作为备用,便于随时回滚

示例配置(Program.cs):

builder.Services.AddApplicationInsightsTelemetry();

9. IIS + Jenkins 零停机最佳实践

✅ 始终保持 Blue / Green 双环境
✅ 每次部署后自动执行 Smoke Test
✅ 若维护用户会话,使用负载均衡会话亲和(Session Affinity)
✅ 使用 appsettings.Production.json 或环境变量进行配置隔离
✅ 在部署前备份数据库结构
✅ 使用预热脚本加载缓存
✅ 明确文档化回滚流程


10. 实际案例

在 SilverXis Pvt Ltd,我们为一个大型 ASP.NET Core + Angular ERP 系统实现了零停机部署。

原先每次发布都会造成数秒的服务中断。
实施蓝绿部署后,QA 可以在 Green 环境验证新版本,
只需一条 PowerShell 命令即可切换到生产流量。

结果:

✅ 0 停机
✅ 快速回滚
✅ 更高的上线信心


11. 流程总结

阶段

描述

工具

Code Commit

开发者推送代码

GitHub

CI Build

构建、测试、发布

Jenkins + .NET CLI

Deploy Green

文件复制、站点启动

PowerShell + IIS

Health Check

验证健康状态

Curl / API Test

Switch Traffic

蓝→绿流量切换

Jenkins + IIS

Monitor & Rollback

监控与回滚

App Insights / ELK


12. 结语

零停机部署,不是 DevOps 的“锦上添花”,
而是企业系统稳定运行的必要条件。借助 ASP.NET Core + IIS + Jenkins,你可以可靠且高效地实现这一目标。通过蓝绿部署模型、CI/CD 自动化和健康检查机制,你的应用可以在任何时间上线新版本 ——  而无需牺牲一秒钟的可用性。

posted @ 2025-12-06 22:11  clnchanpin  阅读(19)  评论(0)    收藏  举报