Jenkins 流水线设计模式
Jenkins Pipeline提供了基础设施即代码的方式来定义CI/CD流程,通过Jenkinsfile将整个构建、测试、部署过程版本化管理。本文深入探讨声明式和脚本式Pipeline的设计模式、最佳实践和高级用法。
🎯 Pipeline 核心概念
声明式 vs 脚本式 Pipeline
groovy
// Declarative Pipeline - 推荐方式
pipeline {
agent {
kubernetes {
yaml '''
apiVersion: v1
kind: Pod
spec:
containers:
- name: maven
image: maven:3.8.1-openjdk-11
command:
- sleep
args:
- 99d
volumeMounts:
- name: docker-sock
mountPath: /var/run/docker.sock
- name: docker
image: docker:20.10
command:
- sleep
args:
- 99d
volumeMounts:
- name: docker-sock
mountPath: /var/run/docker.sock
volumes:
- name: docker-sock
hostPath:
path: /var/run/docker.sock
'''
}
}
environment {
DOCKER_REGISTRY = 'harbor.example.com'
IMAGE_NAME = 'myapp'
KUBECONFIG = credentials('kubeconfig')
SONAR_TOKEN = credentials('sonar-token')
}
parameters {
choice(
name: 'DEPLOY_ENV',
choices: ['dev', 'staging', 'prod'],
description: 'Select deployment environment'
)
booleanParam(
name: 'SKIP_TESTS',
defaultValue: false,
description: 'Skip running tests'
)
string(
name: 'IMAGE_TAG',
defaultValue: 'latest',
description: 'Docker image tag'
)
}
triggers {
pollSCM('H/5 * * * *') // 每5分钟检查SCM变化
cron('H 2 * * 1-5') // 工作日凌晨2点定时构建
upstream(upstreamProjects: 'upstream-job', threshold: hudson.model.Result.SUCCESS)
}
tools {
maven 'Maven-3.8.1'
jdk 'OpenJDK-11'
}
stages {
stage('Preparation') {
steps {
// 并行准备工作
parallel(
"Checkout": {
checkout scm
},
"Environment Check": {
script {
sh 'printenv | sort'
sh 'java -version'
sh 'mvn -version'
}
}
)
}
}
stage('Build') {
steps {
container('maven') {
sh 'mvn clean compile'
}
}
post {
always {
publishTestResults testResultsPattern: 'target/surefire-reports/*.xml'
}
}
}
stage('Test') {
when {
not { params.SKIP_TESTS }
}
parallel {
stage('Unit Tests') {
steps {
container('maven') {
sh 'mvn test'
}
}
post {
always {
junit 'target/surefire-reports/*.xml'
}
}
}
stage('Integration Tests') {
steps {
container('maven') {
sh 'mvn verify -Pfailsafe'
}
}
post {
always {
junit 'target/failsafe-reports/*.xml'
}
}
}
stage('Code Quality') {
steps {
container('maven') {
withSonarQubeEnv('SonarQube') {
sh 'mvn sonar:sonar'
}
}
}
}
}
}
stage('Quality Gate') {
steps {
timeout(time: 10, unit: 'MINUTES') {
waitForQualityGate abortPipeline: true
}
}
}
stage('Package') {
steps {
container('maven') {
sh 'mvn package -DskipTests'
}
container('docker') {
script {
def image = docker.build("${DOCKER_REGISTRY}/${IMAGE_NAME}:${BUILD_NUMBER}")
docker.withRegistry("https://${DOCKER_REGISTRY}", 'harbor-credentials') {
image.push()
image.push("${params.IMAGE_TAG}")
}
}
}
}
}
stage('Deploy') {
when {
anyOf {
branch 'main'
branch 'develop'
expression { params.DEPLOY_ENV == 'prod' }
}
}
steps {
script {
def deploymentFile = "k8s/deployment-${params.DEPLOY_ENV}.yaml"
sh """
sed -i 's|IMAGE_PLACEHOLDER|${DOCKER_REGISTRY}/${IMAGE_NAME}:${BUILD_NUMBER}|g' ${deploymentFile}
kubectl apply -f ${deploymentFile}
kubectl rollout status deployment/myapp -n ${params.DEPLOY_ENV}
"""
}
}
}
}
post {
always {
archiveArtifacts artifacts: 'target/*.jar', fingerprint: true
cleanWs()
}
success {
slackSend(
channel: '#ci-cd',
color: 'good',
message: "✅ Build succeeded: ${env.JOB_NAME} - ${env.BUILD_NUMBER}"
)
}
failure {
slackSend(
channel: '#ci-cd',
color: 'danger',
message: "❌ Build failed: ${env.JOB_NAME} - ${env.BUILD_NUMBER}"
)
}
unstable {
slackSend(
channel: '#ci-cd',
color: 'warning',
message: "⚠️ Build unstable: ${env.JOB_NAME} - ${env.BUILD_NUMBER}"
)
}
}
}groovy
// Scripted Pipeline - 更灵活但复杂
node('kubernetes') {
def dockerRegistry = 'harbor.example.com'
def imageName = 'myapp'
def imageTag = "${BUILD_NUMBER}"
def deployEnv = params.DEPLOY_ENV ?: 'dev'
try {
stage('Preparation') {
// 动态选择构建节点
def buildAgent = selectBuildAgent()
// 检出代码
checkout scm
// 设置构建环境
setupBuildEnvironment()
// 读取构建配置
def buildConfig = readYaml file: '.jenkins/build-config.yaml'
env.BUILD_CONFIG = writeJSON returnText: true, json: buildConfig
}
stage('Build') {
container('maven') {
// 动态Maven目标选择
def mavenGoals = determineMavenGoals(env.BRANCH_NAME)
sh "mvn ${mavenGoals}"
// 构建结果分析
def buildResults = analyzeBuildResults()
if (buildResults.hasCompilationErrors) {
error("Compilation errors found")
}
}
}
stage('Test') {
if (!params.SKIP_TESTS) {
parallel(
'Unit Tests': {
container('maven') {
sh 'mvn test'
publishTestResults testResultsPattern: 'target/surefire-reports/*.xml'
}
},
'Integration Tests': {
container('maven') {
try {
sh 'mvn verify -Pfailsafe'
} catch (Exception e) {
currentBuild.result = 'UNSTABLE'
echo "Integration tests failed: ${e.getMessage()}"
}
}
}
)
}
}
stage('Quality Analysis') {
// 条件执行质量分析
if (shouldRunQualityAnalysis(env.BRANCH_NAME)) {
container('maven') {
withSonarQubeEnv('SonarQube') {
sh 'mvn sonar:sonar'
}
}
// 等待质量门禁
timeout(time: 10, unit: 'MINUTES') {
def qg = waitForQualityGate()
if (qg.status != 'OK') {
error "Pipeline aborted due to quality gate failure: ${qg.status}"
}
}
}
}
stage('Build Image') {
container('docker') {
// 多架构镜像构建
if (params.BUILD_MULTIARCH) {
buildMultiArchImage(dockerRegistry, imageName, imageTag)
} else {
def image = docker.build("${dockerRegistry}/${imageName}:${imageTag}")
// 镜像安全扫描
scanImageForVulnerabilities(image.id)
// 推送镜像
docker.withRegistry("https://${dockerRegistry}", 'harbor-credentials') {
image.push()
image.push("latest")
// 添加额外标签
if (env.BRANCH_NAME == 'main') {
image.push("stable")
}
}
}
}
}
stage('Deploy') {
if (shouldDeploy(env.BRANCH_NAME, deployEnv)) {
// 部署策略选择
def deploymentStrategy = selectDeploymentStrategy(deployEnv)
switch(deploymentStrategy) {
case 'blue-green':
deployBlueGreen(deployEnv, imageTag)
break
case 'canary':
deployCanary(deployEnv, imageTag)
break
case 'rolling':
deployRolling(deployEnv, imageTag)
break
default:
error("Unknown deployment strategy: ${deploymentStrategy}")
}
// 部署后验证
verifyDeployment(deployEnv)
}
}
stage('Post-Deploy Tests') {
if (currentBuild.result != 'FAILURE') {
parallel(
'Smoke Tests': {
runSmokeTests(deployEnv)
},
'Performance Tests': {
if (deployEnv != 'prod') {
runPerformanceTests(deployEnv)
}
}
)
}
}
} catch (Exception e) {
currentBuild.result = 'FAILURE'
throw e
} finally {
stage('Cleanup') {
// 清理工作空间
cleanWs()
// 发送通知
sendNotifications(currentBuild.result)
}
}
}
// 辅助函数定义
def selectBuildAgent() {
// 基于负载选择构建节点
def agents = ['agent-1', 'agent-2', 'agent-3']
return agents[new Random().nextInt(agents.size())]
}
def setupBuildEnvironment() {
// 环境设置逻辑
sh 'printenv | sort'
sh 'java -version'
sh 'docker version'
}
def determineMavenGoals(branchName) {
switch(branchName) {
case 'main':
return 'clean compile'
case 'develop':
return 'clean compile -Pdev'
default:
return 'clean compile -Pfeature'
}
}
def shouldRunQualityAnalysis(branchName) {
return ['main', 'develop'].contains(branchName)
}
def shouldDeploy(branchName, deployEnv) {
if (deployEnv == 'prod') {
return branchName == 'main'
}
return true
}
def deployBlueGreen(env, imageTag) {
echo "Deploying using Blue-Green strategy to ${env}"
// Blue-Green部署逻辑
}
def deployCanary(env, imageTag) {
echo "Deploying using Canary strategy to ${env}"
// Canary部署逻辑
}
def deployRolling(env, imageTag) {
echo "Deploying using Rolling strategy to ${env}"
// Rolling部署逻辑
}Pipeline 高级特性
groovy
// @Library注解引用共享库
@Library(['jenkins-shared-library@main', 'company-utils@v1.2.0']) _
pipeline {
agent none
stages {
stage('Build') {
steps {
// 使用共享库中的构建函数
buildApplication {
buildTool = 'maven'
javaVersion = '11'
mavenGoals = 'clean compile'
}
}
}
stage('Test') {
steps {
// 使用全局变量
script {
utils.runTests(['unit', 'integration'])
}
}
}
stage('Deploy') {
steps {
// 使用共享库中的部署步骤
deployToKubernetes {
environment = params.DEPLOY_ENV
namespace = "myapp-${params.DEPLOY_ENV}"
imageTag = env.BUILD_NUMBER
values = [
'image.repository': 'harbor.example.com/myapp',
'image.tag': env.BUILD_NUMBER,
'ingress.enabled': true
]
}
}
}
}
}groovy
// 多分支Pipeline配置
pipeline {
agent any
stages {
stage('Branch Strategy') {
steps {
script {
// 基于分支名称的不同处理
switch(env.BRANCH_NAME) {
case 'main':
echo 'Production branch detected'
env.DEPLOY_ENV = 'production'
env.RUN_SECURITY_SCAN = 'true'
env.REQUIRE_APPROVAL = 'true'
break
case 'develop':
echo 'Development branch detected'
env.DEPLOY_ENV = 'staging'
env.RUN_SECURITY_SCAN = 'true'
env.REQUIRE_APPROVAL = 'false'
break
case ~/feature\/.+/:
echo 'Feature branch detected'
env.DEPLOY_ENV = 'feature'
env.RUN_SECURITY_SCAN = 'false'
env.REQUIRE_APPROVAL = 'false'
break
case ~/hotfix\/.+/:
echo 'Hotfix branch detected'
env.DEPLOY_ENV = 'hotfix'
env.RUN_SECURITY_SCAN = 'true'
env.REQUIRE_APPROVAL = 'true'
break
default:
echo 'Unknown branch type'
env.DEPLOY_ENV = 'dev'
env.RUN_SECURITY_SCAN = 'false'
env.REQUIRE_APPROVAL = 'false'
}
}
}
}
stage('Build & Test') {
parallel {
stage('Application Build') {
steps {
sh 'mvn clean package -DskipTests'
}
}
stage('Unit Tests') {
steps {
sh 'mvn test'
}
post {
always {
junit 'target/surefire-reports/*.xml'
}
}
}
}
}
stage('Security Scan') {
when {
environment name: 'RUN_SECURITY_SCAN', value: 'true'
}
steps {
// OWASP依赖检查
sh 'mvn org.owasp:dependency-check-maven:check'
// 代码安全扫描
withCredentials([string(credentialsId: 'veracode-api-key', variable: 'VERACODE_API_KEY')]) {
sh 'veracode-scan.sh'
}
}
}
stage('Deployment Approval') {
when {
allOf {
environment name: 'REQUIRE_APPROVAL', value: 'true'
anyOf {
branch 'main'
branch 'hotfix/*'
}
}
}
steps {
script {
def approvers = ['john.doe', 'jane.smith']
def approver = input(
id: 'Deployment',
message: 'Deploy to production?',
submitterParameter: 'APPROVER',
submitter: approvers.join(',')
)
echo "Approved by: ${approver}"
}
}
}
stage('Deploy') {
steps {
script {
deployToEnvironment(env.DEPLOY_ENV)
}
}
}
}
}
def deployToEnvironment(environment) {
switch(environment) {
case 'production':
deployToProduction()
break
case 'staging':
deployToStaging()
break
case 'feature':
deployToFeatureEnvironment()
break
default:
deployToDev()
}
}groovy
pipeline {
agent any
options {
// 构建保留策略
buildDiscarder(logRotator(numToKeepStr: '10'))
// 超时设置
timeout(time: 60, unit: 'MINUTES')
// 时间戳
timestamps()
// 跳过默认检出
skipDefaultCheckout(true)
// 并行构建限制
disableConcurrentBuilds()
}
stages {
stage('Resilient Build') {
steps {
script {
// 重试机制
retry(3) {
try {
checkout scm
sh 'mvn clean compile'
} catch (Exception e) {
echo "Build attempt failed: ${e.getMessage()}"
sleep(time: 30, unit: 'SECONDS') // 等待30秒后重试
throw e
}
}
}
}
}
stage('Flaky Tests') {
steps {
script {
def testAttempts = 0
def maxAttempts = 3
def testsPassed = false
while (!testsPassed && testAttempts < maxAttempts) {
testAttempts++
echo "Test attempt: ${testAttempts}"
try {
sh 'mvn test'
testsPassed = true
} catch (Exception e) {
if (testAttempts >= maxAttempts) {
error("Tests failed after ${maxAttempts} attempts")
}
// 分析测试失败原因
def failureAnalysis = analyzeTestFailures()
if (failureAnalysis.isFlaky) {
echo "Flaky test detected, retrying..."
cleanTestEnvironment()
} else {
error("Genuine test failure detected")
}
}
}
}
}
}
stage('External Service Integration') {
steps {
script {
// 外部服务健康检查
def services = ['database', 'redis', 'elasticsearch']
services.each { service ->
waitUntil(initialRecurrencePeriod: 5000) {
script {
try {
def response = httpRequest(
url: "http://${service}.example.com/health",
timeout: 10
)
return response.status == 200
} catch (Exception e) {
echo "Service ${service} not ready: ${e.getMessage()}"
return false
}
}
}
}
echo "All external services are ready"
}
}
}
stage('Deployment with Rollback') {
steps {
script {
def currentVersion = getCurrentVersion()
try {
// 部署新版本
deployNewVersion()
// 健康检查
def healthCheckPassed = performHealthCheck()
if (!healthCheckPassed) {
throw new Exception("Health check failed")
}
// 流量切换验证
def trafficSwitchSuccessful = switchTrafficGradually()
if (!trafficSwitchSuccessful) {
throw new Exception("Traffic switch failed")
}
} catch (Exception e) {
echo "Deployment failed: ${e.getMessage()}"
// 自动回滚
rollbackToVersion(currentVersion)
// 验证回滚成功
def rollbackHealthy = performHealthCheck()
if (rollbackHealthy) {
echo "Rollback successful"
} else {
error("Rollback failed - manual intervention required")
}
throw e
}
}
}
}
}
post {
failure {
script {
// 故障通知和日志收集
collectFailureLogs()
notifyFailure()
// 如果是主分支失败,创建问题票据
if (env.BRANCH_NAME == 'main') {
createIncidentTicket([
title: "Production build failure",
description: "Build ${env.BUILD_NUMBER} failed on main branch",
priority: "high"
])
}
}
}
}
}
// 辅助函数
def analyzeTestFailures() {
// 分析测试失败日志,判断是否为不稳定测试
def testReports = sh(script: 'find target -name "*.xml" -type f', returnStdout: true).trim()
// 实际分析逻辑...
return [isFlaky: true]
}
def cleanTestEnvironment() {
sh 'docker-compose down && docker-compose up -d'
sleep(time: 10, unit: 'SECONDS')
}
def getCurrentVersion() {
return sh(script: 'kubectl get deployment myapp -o jsonpath="{.spec.template.spec.containers[0].image}"', returnStdout: true).trim()
}
def performHealthCheck() {
def maxAttempts = 10
def attempts = 0
while (attempts < maxAttempts) {
try {
def response = httpRequest url: 'http://myapp.example.com/health', timeout: 30
if (response.status == 200) {
return true
}
} catch (Exception e) {
echo "Health check attempt ${attempts + 1} failed: ${e.getMessage()}"
}
attempts++
sleep(time: 30, unit: 'SECONDS')
}
return false
}📊 Pipeline 设计模式
企业级 Pipeline 模板
yaml
pipeline_templates:
microservice_template:
description: "微服务标准Pipeline模板"
stages:
- "Source Code Checkout"
- "Build & Compile"
- "Unit Testing"
- "Code Quality Analysis"
- "Security Scanning"
- "Container Image Build"
- "Integration Testing"
- "Deployment"
- "Smoke Testing"
- "Performance Testing"
parameters:
service_name: "微服务名称"
build_tool: "构建工具 (maven/gradle/npm)"
deployment_strategy: "部署策略 (blue-green/canary/rolling)"
test_suite: "测试套件配置"
example_implementation: |
@Library('company-pipeline-library@v2.0') _
microservicePipeline {
serviceName = 'user-service'
buildTool = 'maven'
javaVersion = '11'
dockerRegistry = 'harbor.company.com'
kubernetesCluster = 'production-k8s'
deploymentStrategy = 'blue-green'
testing {
unitTests = true
integrationTests = true
contractTests = true
performanceTests = env.BRANCH_NAME == 'main'
}
security {
dependencyCheck = true
staticCodeAnalysis = true
containerScan = true
}
notifications {
slack {
channel = '#devops-alerts'
onFailure = true
onSuccess = false
}
email {
recipients = ['team-lead@company.com']
onFailure = true
}
}
}
frontend_template:
description: "前端应用Pipeline模板"
characteristics:
- "Node.js环境支持"
- "多浏览器测试"
- "性能优化构建"
- "CDN部署集成"
template_usage: |
@Library('frontend-pipeline-library@v1.5') _
frontendPipeline {
nodeVersion = '16'
packageManager = 'npm' // or 'yarn'
build {
command = 'npm run build:prod'
artifactPath = 'dist/'
}
testing {
unitTests {
command = 'npm run test:unit'
coverageThreshold = 80
}
e2eTests {
browsers = ['chrome', 'firefox']
command = 'npm run test:e2e'
}
visualTests {
enabled = true
tool = 'chromatic'
}
}
deployment {
cdn {
provider = 'cloudflare'
distributionId = env.CDN_DISTRIBUTION_ID
invalidationPaths = ['/*']
}
}
}
monorepo_template:
description: "单体仓库Pipeline模板"
features:
- "变更检测"
- "智能构建"
- "依赖管理"
- "并行执行"
implementation: |
@Library('monorepo-pipeline-library@v3.0') _
monorepoPipeline {
structure {
services = [
'services/user-service',
'services/order-service',
'services/payment-service'
]
libraries = [
'libs/common',
'libs/proto'
]
}
changeDetection {
strategy = 'git-diff' // or 'bazel-query'
baseBranch = 'main'
includeTests = true
}
buildStrategy {
parallel = true
maxConcurrency = 4
dependencyOrder = true
}
deployment {
strategy = 'service-by-service'
environment = params.DEPLOY_ENV
rollbackOnFailure = true
}
}yaml
pipeline_best_practices:
fail_fast_pattern:
description: "快速失败模式"
implementation: |
pipeline {
agent any
stages {
stage('Quick Validation') {
parallel {
stage('Syntax Check') {
steps {
sh 'find . -name "*.java" | xargs javac -cp . -d /tmp'
}
}
stage('Lint Check') {
steps {
sh 'mvn spotbugs:check'
}
}
stage('Security Scan') {
steps {
sh 'bandit -r src/ || exit 1'
}
}
}
}
stage('Build') {
when {
expression { currentBuild.result != 'FAILURE' }
}
steps {
sh 'mvn clean package'
}
}
}
}
matrix_builds:
description: "矩阵构建模式"
use_cases:
- "多版本兼容性测试"
- "多平台构建"
- "多环境验证"
example: |
pipeline {
agent none
stages {
stage('Matrix Build') {
matrix {
axes {
axis {
name 'JAVA_VERSION'
values '8', '11', '17'
}
axis {
name 'OS'
values 'linux', 'windows'
}
}
excludes {
exclude {
axis {
name 'JAVA_VERSION'
values '8'
}
axis {
name 'OS'
values 'windows'
}
}
}
stages {
stage('Test') {
agent {
label "${OS}"
}
steps {
script {
if (env.OS == 'windows') {
bat "java -version"
bat "mvn test -Djava.version=${JAVA_VERSION}"
} else {
sh "java -version"
sh "mvn test -Djava.version=${JAVA_VERSION}"
}
}
}
}
}
}
}
}
}
canary_deployment_pattern:
description: "金丝雀部署Pipeline模式"
stages:
- "构建验证"
- "金丝雀部署"
- "监控验证"
- "流量切换"
- "全量部署"
implementation: |
pipeline {
agent any
parameters {
choice(
name: 'CANARY_PERCENTAGE',
choices: ['5', '10', '25', '50'],
description: 'Canary traffic percentage'
)
}
stages {
stage('Build & Test') {
// 标准构建测试阶段
}
stage('Deploy Canary') {
steps {
script {
deployCanary([
image: "${DOCKER_REGISTRY}/${IMAGE_NAME}:${BUILD_NUMBER}",
percentage: params.CANARY_PERCENTAGE,
environment: 'production'
])
}
}
}
stage('Canary Monitoring') {
steps {
script {
def monitoringResults = monitorCanaryDeployment([
duration: '10m',
metrics: [
'error_rate_threshold': 0.01,
'latency_threshold': 500,
'success_rate_threshold': 0.99
]
])
if (!monitoringResults.healthy) {
error("Canary deployment failed monitoring checks")
}
}
}
}
stage('Traffic Increase') {
steps {
script {
def trafficSteps = [10, 25, 50, 100]
for (percentage in trafficSteps) {
echo "Increasing traffic to ${percentage}%"
increaseCanaryTraffic(percentage)
// 监控指定时间
sleep(time: 5, unit: 'MINUTES')
def healthCheck = checkCanaryHealth()
if (!healthCheck.healthy) {
rollbackCanary()
error("Health check failed at ${percentage}% traffic")
}
}
}
}
}
stage('Promote to Production') {
input {
message "Promote canary to full production?"
ok "Promote"
submitterParameter "APPROVER"
}
steps {
promoteCanaryToProduction()
}
}
}
post {
failure {
script {
rollbackCanary()
}
}
}
}Pipeline 性能优化
groovy
// 并行化优化Pipeline
pipeline {
agent none
stages {
stage('Parallel Build') {
parallel {
stage('Backend Build') {
agent { label 'maven' }
steps {
checkout scm
sh 'mvn clean package -DskipTests'
stash includes: 'target/*.jar', name: 'backend-artifacts'
}
}
stage('Frontend Build') {
agent { label 'node' }
steps {
checkout scm
sh 'npm ci'
sh 'npm run build'
stash includes: 'dist/**', name: 'frontend-artifacts'
}
}
stage('Database Migration') {
agent { label 'database' }
steps {
checkout scm
sh 'flyway migrate'
}
}
}
}
stage('Parallel Testing') {
parallel {
stage('Backend Tests') {
agent { label 'maven' }
steps {
unstash 'backend-artifacts'
sh 'mvn test'
sh 'mvn verify'
}
post {
always {
junit 'target/surefire-reports/*.xml'
}
}
}
stage('Frontend Tests') {
agent { label 'node' }
steps {
unstash 'frontend-artifacts'
sh 'npm test'
sh 'npm run test:e2e'
}
}
stage('Security Scan') {
agent { label 'security' }
steps {
checkout scm
sh 'owasp-dependency-check.sh'
sh 'sonarqube-scan.sh'
}
}
}
}
stage('Integration') {
agent any
steps {
unstash 'backend-artifacts'
unstash 'frontend-artifacts'
// 整合构建结果
sh 'docker build -t myapp:${BUILD_NUMBER} .'
}
}
}
}groovy
// 智能缓存策略
pipeline {
agent any
options {
// 保留构建历史
buildDiscarder(logRotator(numToKeepStr: '50'))
// 跳过自动检出,手动控制
skipDefaultCheckout(true)
}
stages {
stage('Smart Checkout') {
steps {
script {
// 检查是否有缓存的依赖
def cacheKey = getCacheKey()
def cacheExists = checkCache(cacheKey)
checkout scm
if (!cacheExists) {
echo "Cache miss, downloading dependencies"
sh 'mvn dependency:go-offline'
cacheArtifacts(cacheKey, '.m2/repository/')
} else {
echo "Cache hit, restoring dependencies"
restoreCache(cacheKey, '.m2/repository/')
}
}
}
}
stage('Incremental Build') {
steps {
script {
// 检测变更的模块
def changedModules = getChangedModules()
if (changedModules.isEmpty()) {
echo "No changes detected, skipping build"
currentBuild.result = 'NOT_BUILT'
return
}
// 只构建变更的模块
changedModules.each { module ->
sh "mvn clean compile -pl ${module} -am"
}
}
}
}
stage('Test Optimization') {
steps {
script {
// 智能测试选择
def testCategories = selectTestCategories()
parallel testCategories.collectEntries { category ->
[category, {
runTestCategory(category)
}]
}
}
}
}
}
}
// 缓存管理函数
def getCacheKey() {
def pomChecksum = sh(
script: "find . -name 'pom.xml' -exec md5sum {} \\; | sort | md5sum | cut -d' ' -f1",
returnStdout: true
).trim()
return "maven-deps-${pomChecksum}"
}
def getChangedModules() {
def changes = sh(
script: "git diff --name-only HEAD~1 HEAD | grep -E '\\.(java|xml)$' | cut -d'/' -f1 | sort -u",
returnStdout: true
).trim().split('\n')
return changes.findAll { it && it != '.' }
}
def selectTestCategories() {
def categories = []
// 基于变更类型选择测试
if (hasCodeChanges()) {
categories.add('unit')
}
if (hasConfigChanges()) {
categories.add('integration')
}
if (env.BRANCH_NAME == 'main') {
categories.addAll(['performance', 'security'])
}
return categories
}groovy
// 动态资源分配Pipeline
pipeline {
agent none
stages {
stage('Resource Planning') {
agent { label 'master' }
steps {
script {
// 评估构建资源需求
def resourceNeeds = assessResourceNeeds()
// 动态分配构建节点
env.BUILD_AGENTS = selectOptimalAgents(resourceNeeds)
echo "Allocated agents: ${env.BUILD_AGENTS}"
}
}
}
stage('Build') {
agent {
label env.BUILD_AGENTS
}
steps {
script {
// 根据可用资源调整并行度
def parallelism = calculateOptimalParallelism()
sh "mvn clean package -T ${parallelism}"
}
}
}
stage('Containerized Testing') {
agent any
steps {
script {
// 使用临时容器进行隔离测试
docker.image('maven:3.8-openjdk-11').inside('-v maven-cache:/root/.m2') {
sh 'mvn test'
}
}
}
post {
always {
// 确保容器清理
sh 'docker system prune -f'
}
}
}
stage('Elastic Deployment') {
agent any
steps {
script {
// 根据负载动态调整部署资源
def deploymentResources = calculateDeploymentResources()
deployWithResources(deploymentResources)
}
}
}
}
post {
always {
script {
// 释放动态分配的资源
cleanupDynamicResources()
}
}
}
}
// 资源管理辅助函数
def assessResourceNeeds() {
def projectSize = sh(
script: "find . -name '*.java' | wc -l",
returnStdout: true
).trim() as Integer
def testCount = sh(
script: "find . -name '*Test.java' | wc -l",
returnStdout: true
).trim() as Integer
return [
cpu: projectSize > 1000 ? 'high' : 'medium',
memory: testCount > 500 ? 'high' : 'medium',
disk: projectSize > 2000 ? 'high' : 'low'
]
}
def selectOptimalAgents(resourceNeeds) {
// 基于需求选择最优构建节点
if (resourceNeeds.cpu == 'high' && resourceNeeds.memory == 'high') {
return 'large-agents'
} else if (resourceNeeds.cpu == 'medium') {
return 'medium-agents'
} else {
return 'small-agents'
}
}
def calculateOptimalParallelism() {
def availableCpus = sh(
script: "nproc",
returnStdout: true
).trim() as Integer
return Math.max(1, availableCpus - 1)
}📋 Pipeline 设计面试重点
基础概念类
声明式Pipeline和脚本式Pipeline的区别?
- 语法结构差异
- 适用场景分析
- 性能和维护性对比
- 错误处理机制差异
Pipeline中agent的作用和类型?
- agent的不同配置方式
- 节点选择策略
- 容器化agent的优势
- 资源管理和优化
如何在Pipeline中实现并行执行?
- parallel块的使用方法
- matrix构建的应用场景
- stash/unstash机制
- 并行执行的最佳实践
高级特性类
Jenkins共享库的设计和使用?
- 共享库的目录结构
- 全局变量和自定义步骤
- 版本管理策略
- 企业级共享库设计
多分支Pipeline的配置和管理?
- 分支策略实现
- 环境配置管理
- 部署策略差异化
- Pull Request集成
Pipeline中的错误处理和重试机制?
- try-catch错误处理
- retry步骤的使用
- post块的应用
- 故障恢复策略
性能优化类
如何优化Pipeline的执行性能?
- 并行化策略
- 缓存机制利用
- 增量构建实现
- 资源分配优化
大型项目的Pipeline设计模式?
- 单体仓库vs多仓库策略
- 微服务Pipeline模板
- 企业级Pipeline标准化
- 性能监控和优化
Pipeline的监控和调试方法?
- 构建日志分析
- 性能指标监控
- 调试工具使用
- 故障排查流程
🔗 相关内容
- Jenkins架构概述 - Jenkins整体架构和组件
- Jenkins分布式构建 - 分布式构建和性能优化
- Jenkins安全配置 - 安全配置和权限管理
- CI/CD基础概念 - CI/CD整体架构设计
Jenkins Pipeline设计是现代CI/CD实践的核心,通过合理的流水线设计和优化,可以实现高效、可靠、可维护的自动化流程。掌握Pipeline的设计模式和最佳实践,是构建企业级CI/CD系统的重要能力。
