9.1 并行执行

并行阶段

声明式Pipeline并行:

pipeline {
    agent any
    
    stages {
        stage('Preparation') {
            steps {
                git 'https://github.com/company/myapp.git'
            }
        }
        
        stage('Parallel Execution') {
            parallel {
                stage('Unit Tests') {
                    steps {
                        echo '运行单元测试...'
                        sh 'mvn test'
                    }
                    post {
                        always {
                            junit '**/target/surefire-reports/*.xml'
                        }
                    }
                }
                
                stage('Integration Tests') {
                    steps {
                        echo '运行集成测试...'
                        sh 'mvn verify -P integration-tests'
                    }
                    post {
                        always {
                            junit '**/target/failsafe-reports/*.xml'
                        }
                    }
                }
                
                stage('Code Quality') {
                    steps {
                        echo '代码质量检查...'
                        sh 'mvn sonar:sonar'
                    }
                }
                
                stage('Security Scan') {
                    steps {
                        echo '安全扫描...'
                        sh 'mvn dependency-check:check'
                    }
                    post {
                        always {
                            publishHTML([
                                allowMissing: false,
                                alwaysLinkToLastBuild: true,
                                keepAll: true,
                                reportDir: 'target/dependency-check-report',
                                reportFiles: 'dependency-check-report.html',
                                reportName: 'Security Report'
                            ])
                        }
                    }
                }
            }
        }
        
        stage('Package') {
            steps {
                echo '打包应用...'
                sh 'mvn package'
            }
        }
    }
}

脚本式Pipeline并行:

node {
    stage('Checkout') {
        git 'https://github.com/company/myapp.git'
    }
    
    stage('Parallel Tests') {
        parallel(
            'Unit Tests': {
                node {
                    echo '运行单元测试...'
                    sh 'mvn test'
                    junit '**/target/surefire-reports/*.xml'
                }
            },
            'Integration Tests': {
                node {
                    echo '运行集成测试...'
                    sh 'mvn verify -P integration-tests'
                    junit '**/target/failsafe-reports/*.xml'
                }
            },
            'Code Quality': {
                node {
                    echo '代码质量检查...'
                    sh 'mvn sonar:sonar'
                }
            },
            'Security Scan': {
                node {
                    echo '安全扫描...'
                    sh 'mvn dependency-check:check'
                    publishHTML([
                        allowMissing: false,
                        alwaysLinkToLastBuild: true,
                        keepAll: true,
                        reportDir: 'target/dependency-check-report',
                        reportFiles: 'dependency-check-report.html',
                        reportName: 'Security Report'
                    ])
                }
            }
        )
    }
    
    stage('Package') {
        echo '打包应用...'
        sh 'mvn package'
    }
}

动态并行

动态生成并行任务:

pipeline {
    agent any
    
    stages {
        stage('Dynamic Parallel') {
            steps {
                script {
                    // 动态生成测试环境列表
                    def environments = ['dev', 'staging', 'qa']
                    def parallelStages = [:]
                    
                    environments.each { env ->
                        parallelStages["Deploy to ${env}"] = {
                            stage("Deploy to ${env}") {
                                echo "部署到 ${env} 环境"
                                sh "./deploy.sh ${env}"
                                
                                // 环境特定的测试
                                sh "./test.sh ${env}"
                            }
                        }
                    }
                    
                    // 执行并行部署
                    parallel parallelStages
                }
            }
        }
    }
}

基于文件的动态并行:

pipeline {
    agent any
    
    stages {
        stage('File-based Parallel') {
            steps {
                script {
                    // 获取所有微服务目录
                    def services = sh(
                        script: 'find services -maxdepth 1 -type d -name "*-service" | sort',
                        returnStdout: true
                    ).trim().split('\n')
                    
                    def parallelBuilds = [:]
                    
                    services.each { service ->
                        def serviceName = service.split('/').last()
                        
                        parallelBuilds["Build ${serviceName}"] = {
                            stage("Build ${serviceName}") {
                                dir(service) {
                                    echo "构建服务: ${serviceName}"
                                    sh 'mvn clean package'
                                    
                                    // 构建Docker镜像
                                    sh "docker build -t ${serviceName}:${env.BUILD_NUMBER} ."
                                    
                                    // 推送到镜像仓库
                                    sh "docker push registry.company.com/${serviceName}:${env.BUILD_NUMBER}"
                                }
                            }
                        }
                    }
                    
                    parallel parallelBuilds
                }
            }
        }
    }
}

并行执行控制

并行失败策略:

pipeline {
    agent any
    
    options {
        // 并行阶段失败时快速失败
        parallelsAlwaysFailFast()
    }
    
    stages {
        stage('Controlled Parallel') {
            parallel {
                stage('Critical Task') {
                    steps {
                        script {
                            try {
                                sh 'critical-command'
                            } catch (Exception e) {
                                // 关键任务失败,标记整个构建失败
                                currentBuild.result = 'FAILURE'
                                error "关键任务失败: ${e.getMessage()}"
                            }
                        }
                    }
                }
                
                stage('Optional Task') {
                    steps {
                        script {
                            try {
                                sh 'optional-command'
                            } catch (Exception e) {
                                // 可选任务失败,标记为不稳定但继续执行
                                currentBuild.result = 'UNSTABLE'
                                echo "可选任务失败: ${e.getMessage()}"
                            }
                        }
                    }
                }
                
                stage('Retry Task') {
                    steps {
                        retry(3) {
                            sh 'flaky-command'
                        }
                    }
                }
            }
        }
    }
}

资源限制并行:

pipeline {
    agent any
    
    stages {
        stage('Resource Limited Parallel') {
            steps {
                script {
                    def databases = ['mysql', 'postgresql', 'mongodb']
                    def parallelTests = [:]
                    
                    databases.each { db ->
                        parallelTests["Test with ${db}"] = {
                            // 使用锁限制并发数据库访问
                            lock(resource: "database-${db}", quantity: 1) {
                                stage("Test with ${db}") {
                                    echo "使用 ${db} 数据库进行测试"
                                    sh "./test-with-db.sh ${db}"
                                }
                            }
                        }
                    }
                    
                    parallel parallelTests
                }
            }
        }
    }
}

9.2 条件执行

when条件

基本when条件:

pipeline {
    agent any
    
    parameters {
        choice(
            name: 'DEPLOY_ENV',
            choices: ['none', 'dev', 'staging', 'production'],
            description: '部署环境'
        )
        booleanParam(
            name: 'SKIP_TESTS',
            defaultValue: false,
            description: '跳过测试'
        )
    }
    
    stages {
        stage('Build') {
            steps {
                sh 'mvn clean compile'
            }
        }
        
        stage('Test') {
            when {
                not { params.SKIP_TESTS }
            }
            steps {
                sh 'mvn test'
            }
        }
        
        stage('Deploy to Dev') {
            when {
                equals expected: 'dev', actual: params.DEPLOY_ENV
            }
            steps {
                echo '部署到开发环境'
                sh './deploy.sh dev'
            }
        }
        
        stage('Deploy to Staging') {
            when {
                equals expected: 'staging', actual: params.DEPLOY_ENV
            }
            steps {
                echo '部署到测试环境'
                sh './deploy.sh staging'
            }
        }
        
        stage('Deploy to Production') {
            when {
                allOf {
                    equals expected: 'production', actual: params.DEPLOY_ENV
                    branch 'main'
                }
            }
            steps {
                echo '部署到生产环境'
                sh './deploy.sh production'
            }
        }
    }
}

分支条件:

pipeline {
    agent any
    
    stages {
        stage('Feature Branch') {
            when {
                branch 'feature/*'
            }
            steps {
                echo '功能分支构建'
                sh 'mvn clean test'
            }
        }
        
        stage('Main Branch') {
            when {
                branch 'main'
            }
            steps {
                echo '主分支构建'
                sh 'mvn clean package'
            }
        }
        
        stage('Release Branch') {
            when {
                branch 'release/*'
            }
            steps {
                echo '发布分支构建'
                sh 'mvn clean package -P release'
            }
        }
        
        stage('Pull Request') {
            when {
                changeRequest()
            }
            steps {
                echo 'Pull Request构建'
                sh 'mvn clean verify'
            }
        }
    }
}

环境变量条件:

pipeline {
    agent any
    
    environment {
        BUILD_TYPE = 'release'
        DEPLOY_ENABLED = 'true'
    }
    
    stages {
        stage('Debug Build') {
            when {
                environment name: 'BUILD_TYPE', value: 'debug'
            }
            steps {
                echo '调试构建'
                sh 'mvn clean compile -P debug'
            }
        }
        
        stage('Release Build') {
            when {
                environment name: 'BUILD_TYPE', value: 'release'
            }
            steps {
                echo '发布构建'
                sh 'mvn clean package -P release'
            }
        }
        
        stage('Deploy') {
            when {
                allOf {
                    environment name: 'DEPLOY_ENABLED', value: 'true'
                    branch 'main'
                }
            }
            steps {
                echo '执行部署'
                sh './deploy.sh'
            }
        }
    }
}

文件变化条件:

pipeline {
    agent any
    
    stages {
        stage('Frontend Build') {
            when {
                changeset 'frontend/**'
            }
            steps {
                echo '前端代码变化,构建前端'
                dir('frontend') {
                    sh 'npm install'
                    sh 'npm run build'
                }
            }
        }
        
        stage('Backend Build') {
            when {
                changeset 'backend/**'
            }
            steps {
                echo '后端代码变化,构建后端'
                dir('backend') {
                    sh 'mvn clean package'
                }
            }
        }
        
        stage('Database Migration') {
            when {
                changeset 'database/migrations/**'
            }
            steps {
                echo '数据库迁移文件变化,执行迁移'
                sh './migrate.sh'
            }
        }
        
        stage('Documentation') {
            when {
                changeset 'docs/**'
            }
            steps {
                echo '文档变化,生成文档'
                sh 'mkdocs build'
            }
        }
    }
}

复杂条件组合:

pipeline {
    agent any
    
    parameters {
        choice(
            name: 'ENVIRONMENT',
            choices: ['dev', 'staging', 'production'],
            description: '目标环境'
        )
        booleanParam(
            name: 'FORCE_DEPLOY',
            defaultValue: false,
            description: '强制部署'
        )
    }
    
    stages {
        stage('Conditional Deploy') {
            when {
                anyOf {
                    // 主分支且目标是生产环境
                    allOf {
                        branch 'main'
                        equals expected: 'production', actual: params.ENVIRONMENT
                    }
                    // 开发分支且目标是开发环境
                    allOf {
                        branch 'develop'
                        equals expected: 'dev', actual: params.ENVIRONMENT
                    }
                    // 强制部署
                    params.FORCE_DEPLOY
                }
            }
            steps {
                echo "部署到 ${params.ENVIRONMENT} 环境"
                sh "./deploy.sh ${params.ENVIRONMENT}"
            }
        }
        
        stage('Security Scan') {
            when {
                anyOf {
                    // 生产部署前必须安全扫描
                    equals expected: 'production', actual: params.ENVIRONMENT
                    // 每周一自动安全扫描
                    expression {
                        return new Date().format('u') == '1'
                    }
                }
            }
            steps {
                echo '执行安全扫描'
                sh 'security-scan.sh'
            }
        }
    }
}

脚本式条件

脚本式Pipeline条件:

node {
    def branchName = env.BRANCH_NAME
    def buildNumber = env.BUILD_NUMBER.toInteger()
    
    stage('Conditional Logic') {
        // 基于分支的条件
        if (branchName == 'main') {
            echo '主分支:执行完整构建'
            sh 'mvn clean package'
            
            // 生产部署
            if (buildNumber % 5 == 0) {
                echo '每5次构建部署到生产环境'
                sh './deploy-production.sh'
            }
            
        } else if (branchName.startsWith('feature/')) {
            echo '功能分支:执行基础构建'
            sh 'mvn clean compile test'
            
        } else if (branchName.startsWith('release/')) {
            echo '发布分支:执行发布构建'
            sh 'mvn clean package -P release'
            
            // 部署到预发布环境
            sh './deploy-staging.sh'
            
        } else {
            echo '其他分支:跳过构建'
            return
        }
    }
    
    stage('Conditional Tests') {
        // 基于时间的条件
        def hour = new Date().format('HH').toInteger()
        
        if (hour >= 9 && hour <= 17) {
            echo '工作时间:运行快速测试'
            sh 'mvn test -P quick-tests'
        } else {
            echo '非工作时间:运行完整测试'
            sh 'mvn test'
        }
    }
    
    stage('Conditional Notifications') {
        // 基于构建结果的条件
        if (currentBuild.result == 'SUCCESS' || currentBuild.result == null) {
            echo '构建成功:发送成功通知'
            slackSend(
                channel: '#ci-cd',
                color: 'good',
                message: "✅ 构建成功: ${env.JOB_NAME} #${env.BUILD_NUMBER}"
            )
        } else {
            echo '构建失败:发送失败通知'
            slackSend(
                channel: '#ci-cd',
                color: 'danger',
                message: "❌ 构建失败: ${env.JOB_NAME} #${env.BUILD_NUMBER}"
            )
        }
    }
}

9.3 输入和批准

用户输入

简单输入:

pipeline {
    agent any
    
    stages {
        stage('Build') {
            steps {
                sh 'mvn clean package'
            }
        }
        
        stage('Deploy Approval') {
            steps {
                script {
                    // 简单的是/否确认
                    def userInput = input(
                        message: '是否部署到生产环境?',
                        ok: '部署',
                        submitterParameter: 'APPROVER'
                    )
                    
                    echo "部署批准者: ${env.APPROVER}"
                }
            }
        }
        
        stage('Deploy') {
            steps {
                echo '部署到生产环境'
                sh './deploy-production.sh'
            }
        }
    }
}

参数化输入:

pipeline {
    agent any
    
    stages {
        stage('Build') {
            steps {
                sh 'mvn clean package'
            }
        }
        
        stage('Deployment Configuration') {
            steps {
                script {
                    def deployConfig = input(
                        message: '配置部署参数',
                        ok: '确认部署',
                        submitterParameter: 'APPROVER',
                        parameters: [
                            choice(
                                name: 'ENVIRONMENT',
                                choices: ['staging', 'production'],
                                description: '部署环境'
                            ),
                            string(
                                name: 'VERSION',
                                defaultValue: env.BUILD_NUMBER,
                                description: '版本号'
                            ),
                            booleanParam(
                                name: 'ROLLBACK_ENABLED',
                                defaultValue: true,
                                description: '启用回滚'
                            ),
                            text(
                                name: 'RELEASE_NOTES',
                                defaultValue: '',
                                description: '发布说明'
                            )
                        ]
                    )
                    
                    // 使用输入参数
                    env.DEPLOY_ENV = deployConfig.ENVIRONMENT
                    env.DEPLOY_VERSION = deployConfig.VERSION
                    env.ROLLBACK_ENABLED = deployConfig.ROLLBACK_ENABLED
                    env.RELEASE_NOTES = deployConfig.RELEASE_NOTES
                    
                    echo "部署环境: ${env.DEPLOY_ENV}"
                    echo "版本号: ${env.DEPLOY_VERSION}"
                    echo "回滚启用: ${env.ROLLBACK_ENABLED}"
                    echo "发布说明: ${env.RELEASE_NOTES}"
                    echo "批准者: ${env.APPROVER}"
                }
            }
        }
        
        stage('Deploy') {
            steps {
                sh "./deploy.sh ${env.DEPLOY_ENV} ${env.DEPLOY_VERSION}"
            }
        }
    }
}

超时输入:

pipeline {
    agent any
    
    stages {
        stage('Automated Tests') {
            steps {
                sh 'mvn test'
            }
        }
        
        stage('Manual Testing Approval') {
            steps {
                script {
                    try {
                        timeout(time: 24, unit: 'HOURS') {
                            def testResult = input(
                                message: '手动测试完成了吗?',
                                ok: '测试完成',
                                submitterParameter: 'TESTER',
                                parameters: [
                                    choice(
                                        name: 'TEST_RESULT',
                                        choices: ['PASS', 'FAIL', 'PARTIAL'],
                                        description: '测试结果'
                                    ),
                                    text(
                                        name: 'TEST_NOTES',
                                        defaultValue: '',
                                        description: '测试备注'
                                    )
                                ]
                            )
                            
                            if (testResult.TEST_RESULT == 'FAIL') {
                                error "手动测试失败: ${testResult.TEST_NOTES}"
                            } else if (testResult.TEST_RESULT == 'PARTIAL') {
                                currentBuild.result = 'UNSTABLE'
                                echo "部分测试通过: ${testResult.TEST_NOTES}"
                            }
                            
                            echo "测试者: ${env.TESTER}"
                            echo "测试结果: ${testResult.TEST_RESULT}"
                            echo "测试备注: ${testResult.TEST_NOTES}"
                        }
                    } catch (org.jenkinsci.plugins.workflow.steps.FlowInterruptedException e) {
                        echo '手动测试超时,自动继续部署'
                        currentBuild.result = 'UNSTABLE'
                    }
                }
            }
        }
        
        stage('Deploy') {
            steps {
                echo '部署应用'
                sh './deploy.sh'
            }
        }
    }
}

多阶段批准

分级批准:

pipeline {
    agent any
    
    stages {
        stage('Build and Test') {
            steps {
                sh 'mvn clean package'
                sh 'mvn test'
            }
        }
        
        stage('QA Approval') {
            steps {
                script {
                    def qaApproval = input(
                        message: 'QA团队批准部署到测试环境?',
                        ok: 'QA批准',
                        submitter: 'qa-team',
                        submitterParameter: 'QA_APPROVER',
                        parameters: [
                            booleanParam(
                                name: 'QA_PASSED',
                                defaultValue: false,
                                description: 'QA测试通过'
                            )
                        ]
                    )
                    
                    if (!qaApproval.QA_PASSED) {
                        error 'QA测试未通过,停止部署'
                    }
                    
                    echo "QA批准者: ${env.QA_APPROVER}"
                }
            }
        }
        
        stage('Deploy to Staging') {
            steps {
                echo '部署到测试环境'
                sh './deploy-staging.sh'
            }
        }
        
        stage('DevOps Approval') {
            steps {
                script {
                    def devopsApproval = input(
                        message: 'DevOps团队批准部署到生产环境?',
                        ok: 'DevOps批准',
                        submitter: 'devops-team,release-manager',
                        submitterParameter: 'DEVOPS_APPROVER',
                        parameters: [
                            choice(
                                name: 'DEPLOYMENT_STRATEGY',
                                choices: ['blue-green', 'rolling', 'canary'],
                                description: '部署策略'
                            ),
                            string(
                                name: 'MAINTENANCE_WINDOW',
                                defaultValue: '02:00-04:00',
                                description: '维护窗口'
                            )
                        ]
                    )
                    
                    env.DEPLOYMENT_STRATEGY = devopsApproval.DEPLOYMENT_STRATEGY
                    env.MAINTENANCE_WINDOW = devopsApproval.MAINTENANCE_WINDOW
                    
                    echo "DevOps批准者: ${env.DEVOPS_APPROVER}"
                    echo "部署策略: ${env.DEPLOYMENT_STRATEGY}"
                    echo "维护窗口: ${env.MAINTENANCE_WINDOW}"
                }
            }
        }
        
        stage('Deploy to Production') {
            steps {
                echo "使用${env.DEPLOYMENT_STRATEGY}策略部署到生产环境"
                sh "./deploy-production.sh --strategy=${env.DEPLOYMENT_STRATEGY}"
            }
        }
    }
}

条件批准:

pipeline {
    agent any
    
    parameters {
        choice(
            name: 'DEPLOY_TYPE',
            choices: ['hotfix', 'feature', 'release'],
            description: '部署类型'
        )
    }
    
    stages {
        stage('Build') {
            steps {
                sh 'mvn clean package'
            }
        }
        
        stage('Conditional Approval') {
            steps {
                script {
                    def needsApproval = false
                    def approvers = ''
                    def message = ''
                    
                    switch (params.DEPLOY_TYPE) {
                        case 'hotfix':
                            needsApproval = true
                            approvers = 'senior-dev,tech-lead'
                            message = '紧急修复需要高级开发者批准'
                            break
                        case 'feature':
                            needsApproval = env.BRANCH_NAME == 'main'
                            approvers = 'product-owner,tech-lead'
                            message = '功能发布需要产品负责人批准'
                            break
                        case 'release':
                            needsApproval = true
                            approvers = 'release-manager,cto'
                            message = '正式发布需要发布经理批准'
                            break
                    }
                    
                    if (needsApproval) {
                        def approval = input(
                            message: message,
                            ok: '批准部署',
                            submitter: approvers,
                            submitterParameter: 'APPROVER',
                            parameters: [
                                text(
                                    name: 'APPROVAL_REASON',
                                    defaultValue: '',
                                    description: '批准理由'
                                )
                            ]
                        )
                        
                        echo "批准者: ${env.APPROVER}"
                        echo "批准理由: ${approval.APPROVAL_REASON}"
                    } else {
                        echo '无需批准,自动部署'
                    }
                }
            }
        }
        
        stage('Deploy') {
            steps {
                echo "执行${params.DEPLOY_TYPE}部署"
                sh "./deploy.sh --type=${params.DEPLOY_TYPE}"
            }
        }
    }
}

9.4 错误处理和重试

异常处理

try-catch处理:

pipeline {
    agent any
    
    stages {
        stage('Risky Operations') {
            steps {
                script {
                    try {
                        echo '执行可能失败的操作'
                        sh 'risky-command'
                        
                    } catch (Exception e) {
                        echo "捕获异常: ${e.getMessage()}"
                        
                        // 记录错误详情
                        writeFile file: 'error.log', text: "${new Date()}: ${e.getMessage()}\n${e.getStackTrace().join('\n')}"
                        
                        // 发送通知
                        emailext (
                            subject: "构建失败: ${env.JOB_NAME} #${env.BUILD_NUMBER}",
                            body: "构建失败,错误信息: ${e.getMessage()}",
                            to: 'team@company.com'
                        )
                        
                        // 设置构建状态
                        currentBuild.result = 'FAILURE'
                        
                        // 重新抛出异常
                        throw e
                    }
                }
            }
        }
    }
}

分类错误处理:

pipeline {
    agent any
    
    stages {
        stage('Comprehensive Error Handling') {
            steps {
                script {
                    try {
                        // 编译阶段
                        echo '编译代码...'
                        def compileResult = sh(
                            script: 'mvn compile',
                            returnStatus: true
                        )
                        
                        if (compileResult != 0) {
                            throw new Exception('编译失败')
                        }
                        
                        // 测试阶段
                        echo '运行测试...'
                        def testResult = sh(
                            script: 'mvn test',
                            returnStatus: true
                        )
                        
                        if (testResult != 0) {
                            throw new Exception('测试失败')
                        }
                        
                        // 部署阶段
                        echo '部署应用...'
                        def deployResult = sh(
                            script: './deploy.sh',
                            returnStatus: true
                        )
                        
                        if (deployResult != 0) {
                            throw new Exception('部署失败')
                        }
                        
                    } catch (Exception e) {
                        def errorMessage = e.getMessage()
                        
                        switch (errorMessage) {
                            case '编译失败':
                                echo '编译错误处理'
                                currentBuild.result = 'FAILURE'
                                
                                // 发送给开发团队
                                slackSend(
                                    channel: '#dev-team',
                                    color: 'danger',
                                    message: "🔴 编译失败: ${env.JOB_NAME} #${env.BUILD_NUMBER}"
                                )
                                break
                                
                            case '测试失败':
                                echo '测试错误处理'
                                currentBuild.result = 'UNSTABLE'
                                
                                // 发送给QA团队
                                slackSend(
                                    channel: '#qa-team',
                                    color: 'warning',
                                    message: "⚠️ 测试失败: ${env.JOB_NAME} #${env.BUILD_NUMBER}"
                                )
                                break
                                
                            case '部署失败':
                                echo '部署错误处理'
                                currentBuild.result = 'FAILURE'
                                
                                // 执行回滚
                                sh './rollback.sh'
                                
                                // 发送给运维团队
                                slackSend(
                                    channel: '#ops-team',
                                    color: 'danger',
                                    message: "🚨 部署失败并已回滚: ${env.JOB_NAME} #${env.BUILD_NUMBER}"
                                )
                                break
                                
                            default:
                                echo '未知错误处理'
                                currentBuild.result = 'FAILURE'
                                
                                // 发送给所有团队
                                slackSend(
                                    channel: '#ci-cd',
                                    color: 'danger',
                                    message: "❌ 未知错误: ${env.JOB_NAME} #${env.BUILD_NUMBER} - ${errorMessage}"
                                )
                        }
                        
                        throw e
                    }
                }
            }
        }
    }
}

重试机制

简单重试:

pipeline {
    agent any
    
    stages {
        stage('Flaky Operations') {
            steps {
                // 重试整个步骤
                retry(3) {
                    echo '执行可能不稳定的操作'
                    sh 'flaky-command'
                }
            }
        }
        
        stage('Network Operations') {
            steps {
                script {
                    // 重试特定操作
                    retry(5) {
                        echo '尝试网络操作'
                        sh 'curl -f https://api.example.com/health'
                    }
                }
            }
        }
    }
}

智能重试:

pipeline {
    agent any
    
    stages {
        stage('Smart Retry') {
            steps {
                script {
                    def maxRetries = 3
                    def retryCount = 0
                    def success = false
                    
                    while (!success && retryCount < maxRetries) {
                        try {
                            retryCount++
                            echo "尝试第 ${retryCount} 次"
                            
                            // 执行操作
                            sh 'unstable-operation'
                            
                            success = true
                            echo '操作成功'
                            
                        } catch (Exception e) {
                            echo "第 ${retryCount} 次尝试失败: ${e.getMessage()}"
                            
                            if (retryCount < maxRetries) {
                                // 指数退避
                                def waitTime = Math.pow(2, retryCount) * 10
                                echo "等待 ${waitTime} 秒后重试"
                                sleep(time: waitTime, unit: 'SECONDS')
                            } else {
                                echo '达到最大重试次数,操作失败'
                                throw e
                            }
                        }
                    }
                }
            }
        }
    }
}

条件重试:

pipeline {
    agent any
    
    stages {
        stage('Conditional Retry') {
            steps {
                script {
                    def retryableErrors = ['timeout', 'network', 'temporary']
                    def maxRetries = 3
                    def retryCount = 0
                    
                    while (retryCount < maxRetries) {
                        try {
                            retryCount++
                            echo "执行操作 (尝试 ${retryCount}/${maxRetries})"
                            
                            // 模拟可能失败的操作
                            def result = sh(
                                script: 'complex-operation',
                                returnStdout: true
                            ).trim()
                            
                            echo '操作成功完成'
                            break
                            
                        } catch (Exception e) {
                            def errorMessage = e.getMessage().toLowerCase()
                            def shouldRetry = retryableErrors.any { error ->
                                errorMessage.contains(error)
                            }
                            
                            if (shouldRetry && retryCount < maxRetries) {
                                echo "检测到可重试错误: ${e.getMessage()}"
                                echo "等待后重试..."
                                sleep(time: 30, unit: 'SECONDS')
                            } else {
                                echo "不可重试错误或达到最大重试次数: ${e.getMessage()}"
                                throw e
                            }
                        }
                    }
                }
            }
        }
    }
}

超时处理

阶段超时:

pipeline {
    agent any
    
    stages {
        stage('Quick Operation') {
            options {
                timeout(time: 5, unit: 'MINUTES')
            }
            steps {
                echo '快速操作'
                sh 'quick-command'
            }
        }
        
        stage('Long Operation') {
            options {
                timeout(time: 1, unit: 'HOURS')
            }
            steps {
                echo '长时间操作'
                sh 'long-running-command'
            }
        }
        
        stage('Critical Operation') {
            steps {
                script {
                    try {
                        timeout(time: 30, unit: 'MINUTES') {
                            echo '关键操作'
                            sh 'critical-command'
                        }
                    } catch (org.jenkinsci.plugins.workflow.steps.FlowInterruptedException e) {
                        echo '关键操作超时,执行应急处理'
                        
                        // 清理资源
                        sh 'cleanup-resources'
                        
                        // 发送警报
                        slackSend(
                            channel: '#alerts',
                            color: 'danger',
                            message: "🚨 关键操作超时: ${env.JOB_NAME} #${env.BUILD_NUMBER}"
                        )
                        
                        // 标记为失败
                        currentBuild.result = 'FAILURE'
                        throw e
                    }
                }
            }
        }
    }
}

全局超时:

pipeline {
    agent any
    
    options {
        // 整个Pipeline超时
        timeout(time: 2, unit: 'HOURS')
    }
    
    stages {
        stage('Build') {
            steps {
                sh 'mvn clean compile'
            }
        }
        
        stage('Test') {
            steps {
                sh 'mvn test'
            }
        }
        
        stage('Deploy') {
            steps {
                sh './deploy.sh'
            }
        }
    }
    
    post {
        aborted {
            echo 'Pipeline被中止(可能是超时)'
            
            // 清理资源
            sh 'cleanup-all-resources'
            
            // 发送通知
            emailext (
                subject: "Pipeline超时中止: ${env.JOB_NAME} #${env.BUILD_NUMBER}",
                body: "Pipeline执行超过2小时被自动中止",
                to: 'team@company.com'
            )
        }
    }
}

本章小结

本章深入介绍了Jenkins Pipeline的高级特性,包括:

  1. 并行执行:学习如何使用并行阶段提高构建效率
  2. 条件执行:掌握when条件和脚本式条件的使用
  3. 输入和批准:了解用户输入和多阶段批准流程
  4. 错误处理和重试:学习异常处理、重试机制和超时处理

这些高级特性使Pipeline能够处理复杂的CI/CD场景,提供更好的用户体验和更高的可靠性。

下一章预告

下一章我们将学习Jenkins的共享库,了解如何创建可重用的Pipeline代码。

练习与思考

理论练习

  1. 并行策略设计

    • 分析哪些阶段适合并行执行
    • 设计资源限制的并行策略
    • 考虑并行失败的处理方案
  2. 条件执行设计

    • 设计基于分支的部署策略
    • 考虑环境变量的条件逻辑
    • 分析文件变化的触发条件

实践练习

  1. 并行Pipeline实现

    • 创建包含并行测试的Pipeline
    • 实现动态并行任务生成
    • 添加并行执行的错误处理
  2. 批准流程实现

    • 设计多级批准流程
    • 实现条件批准逻辑
    • 添加超时和默认处理

思考题

  1. 性能优化

    • 如何平衡并行度和资源使用?
    • 如何优化Pipeline的执行时间?
    • 如何处理并行任务的依赖关系?
  2. 可靠性设计

    • 如何设计健壮的错误处理机制?
    • 如何实现智能重试策略?
    • 如何处理长时间运行的任务?