SpringBoot自动化部署实战指南

SpringBoot自动化部署实战指南

一、整体部署架构设计

典型部署架构

代码推送
Webhook
构建
部署
开发者
GitHub/GitLab
Jenkins/CI Server
Docker Registry
Kubernetes Cluster
SpringBoot Pod 1
SpringBoot Pod 2
SpringBoot Pod 3
MySQL
Redis
Elasticsearch

二、基础部署方案

1. 快速启动脚本

#!/bin/bash
# deploy.sh

APP_NAME="my-springboot-app"
JAR_PATH="target/$APP_NAME.jar"
PROFILE="prod"
SERVER_IP="192.168.1.100"
DEPLOY_DIR="/opt/apps"

# 构建应用
mvn clean package -DskipTests

# 传输文件
scp $JAR_PATH $SERVER_IP:$DEPLOY_DIR

# 远程部署
ssh $SERVER_IP "sudo systemctl stop $APP_NAME || true"
ssh $SERVER_IP "cd $DEPLOY_DIR && nohup java -jar $APP_NAME.jar --spring.profiles.active=$PROFILE > app.log 2>&1 &"

2. Systemd服务配置

# /etc/systemd/system/my-springboot-app.service
[Unit]
Description=My SpringBoot Application
After=syslog.target network.target

[Service]
User=appuser
WorkingDirectory=/opt/apps
ExecStart=/usr/bin/java -jar /opt/apps/my-springboot-app.jar --spring.profiles.active=prod
SuccessExitStatus=143
Restart=always
RestartSec=30
Environment="JAVA_OPTS=-Xms512m -Xmx1024m -XX:MaxMetaspaceSize=256m"

[Install]
WantedBy=multi-user.target

三、Docker化部署方案

1. Dockerfile多阶段构建

# 构建阶段
FROM eclipse-temurin:17-jdk-jammy AS builder
WORKDIR /app
COPY . ./
RUN ./mvnw clean package -DskipTests

# 生产阶段
FROM eclipse-temurin:17-jre-jammy
VOLUME /tmp
WORKDIR /app
COPY --from=builder /app/target/*.jar app.jar

# 安全增强
RUN addgroup --system spring && adduser --system --ingroup spring springuser
USER springuser

# 健康检查
HEALTHCHECK --interval=30s --timeout=3s \
  CMD curl -f http://localhost:8080/actuator/health || exit 1

EXPOSE 8080
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar"]

2. Docker Compose部署

version: '3.8'

services:
  app:
    image: my-registry.com/spring-app:${TAG:-latest}
    build: 
      context: .
      target: builder # 仅用于开发环境
    environment:
      - SPRING_PROFILES_ACTIVE=prod
      - SPRING_DATASOURCE_URL=jdbc:mysql://db:3306/app_db
    ports:
      - "8080:8080"
    depends_on:
      - db
      - redis

  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: rootpass
      MYSQL_DATABASE: app_db
      MYSQL_USER: appuser
      MYSQL_PASSWORD: secret
    volumes:
      - mysql_data:/var/lib/mysql

  redis:
    image: redis:6-alpine
    command: redis-server --requirepass ${REDIS_PASSWORD}

  prometheus:
    image: prom/prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml

volumes:
  mysql_data:

四、CI/CD自动化流水线

GitHub Actions工作流

name: Build, Test & Deploy

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    
    - name: Set up JDK 17
      uses: actions/setup-java@v3
      with:
        java-version: '17'
        distribution: 'temurin'
        cache: 'maven'
    
    - name: Build and Test
      run: mvn clean verify
      
    - name: Docker Build
      uses: docker/build-push-action@v3
      with:
        context: .
        push: false
        tags: my-spring-app:pr-${{ github.sha }}
        
  deploy-prod:
    needs: build
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    environment: production
    steps:
    - name: Deploy to Kubernetes
      uses: steebchen/kubectl@v2.0.0
      with:
        kubectl-version: v1.23.0
        config: ${{ secrets.KUBECONFIG }}
        command: apply -f k8s/deployment.yaml

Jenkins Pipeline脚本

pipeline {
    agent any
    environment {
        DOCKER_REGISTRY = "my-registry.com"
        KUBE_CONTEXT = "prod-cluster"
    }
    stages {
        stage('Build') {
            steps {
                sh 'mvn clean package -DskipTests'
                archiveArtifacts artifacts: 'target/*.jar', fingerprint: true
            }
        }
        stage('Test') {
            steps {
                parallel(
                    "Unit Tests": { sh 'mvn test' },
                    "Integration Tests": { sh 'mvn verify -Pintegration' }
                )
            }
        }
        stage('Docker Build') {
            steps {
                script {
                    def imageName = "${DOCKER_REGISTRY}/spring-app:${env.BUILD_ID}"
                    docker.build(imageName).push()
                }
            }
        }
        stage('Deploy to Staging') {
            steps {
                withKubeConfig([credentialsId: 'k8s-prod-creds']) {
                    sh "kubectl config use-context ${KUBE_CONTEXT}"
                    sh "kubectl apply -f k8s/staging/deployment.yaml"
                }
            }
        }
    }
}

五、Kubernetes部署方案

1. Deployment配置

apiVersion: apps/v1
kind: Deployment
metadata:
  name: springboot-app
spec:
  replicas: 3
  revisionHistoryLimit: 3
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
    type: RollingUpdate
  selector:
    matchLabels:
      app: springboot-app
  template:
    metadata:
      labels:
        app: springboot-app
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "8080"
    spec:
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - springboot-app
              topologyKey: "kubernetes.io/hostname"
      containers:
      - name: app
        image: my-registry.com/spring-app:latest
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
        envFrom:
        - configMapRef:
            name: app-config
        - secretRef:
            name: db-secrets
        resources:
          requests:
            cpu: "500m"
            memory: "512Mi"
          limits:
            cpu: "1000m"
            memory: "1024Mi"
        livenessProbe:
          httpGet:
            path: /actuator/health/liveness
            port: 8080
          initialDelaySeconds: 45
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /actuator/health/readiness
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 5

2. 配置管理(ConfigMap + Secrets)

# ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  application.properties: |
    server.port=8080
    spring.datasource.url=jdbc:mysql://mysql-service:3306/app_db
    spring.jpa.hibernate.ddl-auto=validate
    spring.cache.type=redis
    
# Secrets
apiVersion: v1
kind: Secret
metadata:
  name: db-secrets
type: Opaque
stringData:
  spring.datasource.username: appuser
  spring.datasource.password: "securepassword123"

六、高级部署策略

1. 蓝绿部署流程

# 部署新版本(绿色环境)
kubectl apply -f green-deployment.yaml

# 测试新版本
kubectl run test-container --image=curlimages/curl --rm -it -- \
  curl http://green-service/actuator/health

# 切换流量
kubectl patch svc main-service -p \
  '{"spec":{"selector":{"app":"springboot-app","version":"green"}}}'

# 清理旧版本
kubectl delete -f blue-deployment.yaml

2. 金丝雀发布自动化

# Argo Rollouts 配置
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: springboot-app
spec:
  replicas: 5
  strategy:
    canary:
      steps:
      - setWeight: 10
      - pause: {duration: 5m} # 监控指标
      - setWeight: 25
      - pause: {duration: 5m}
      - setWeight: 50
      - pause: {duration: 10m}
      - setWeight: 100
  selector:
    matchLabels:
      app: springboot-app
  template:
    # 与标准Deployment相同

七、监控与运维

Prometheus监控配置

# prometheus.yml
scrape_configs:
  - job_name: 'springboot-app'
    metrics_path: '/actuator/prometheus'
    kubernetes_sd_configs:
    - role: pod
    relabel_configs:
    - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
      action: keep
      regex: true
    - source_labels: [__address__]
      action: replace
      regex: ([^:]+)(?::\d+)?
      replacement: $1:8080
      target_label: __address__
      
  - job_name: 'jvm'
    static_configs:
    - targets: ['jvm-exporter:9400']

Spring Boot Actuator配置

management:
  endpoints:
    web:
      exposure:
        include: "*"
  endpoint:
    health:
      show-details: always
      probes:
        enabled: true
    metrics:
      enabled: true
  metrics:
    export:
      prometheus:
        enabled: true
    tags:
      application: ${spring.application.name}
    distribution:
      percentiles-histogram:
        http.server.requests: true

八、安全加固措施

1. 安全基线配置

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable() // 仅用于API服务,前端应用需启用
            .headers()
                .contentSecurityPolicy("default-src 'self'")
                .and()
                .xssProtection().xssProtectionEnabled(true)
                .and()
                .httpStrictTransportSecurity()
                .maxAgeInSeconds(31536000)
                .includeSubDomains(true)
                .and()
                .frameOptions().deny();
        
        http
            .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }
}

2. 容器安全扫描

# 使用Trivy扫描镜像
docker run --rm \
  -v /var/run/docker.sock:/var/run/docker.sock \
  aquasec/trivy image my-registry.com/spring-app:latest
  
# 结果示例
+-------------------+------------------+----------+-------------------+---------+--------------------------------+
|     LIBRARY       | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED   |             TITLE              |
+-------------------+------------------+----------+-------------------+---------+--------------------------------+
| apt               | CVE-2023-XXXXX   | HIGH     | 2.4.8             | 2.4.9   | APT 安全漏洞                  |
| openjdk-17-jre    | CVE-2023-YYYYY   | MEDIUM   | 17.0.6            | 17.0.7  | OpenJDK 漏洞                  |
+-------------------+------------------+----------+-------------------+---------+--------------------------------+

九、最佳实践总结

部署流程优化

  1. 自动化测试:集成单元测试、集成测试、安全扫描
  2. 不可变基础设施:每次部署创建新镜像而非更新现有实例
  3. 渐进式交付:结合蓝绿部署和金丝雀发布
  4. 回滚策略:保留最近3个版本,支持10秒内回滚
  5. 配置分离:敏感信息使用Secret管理,配置使用ConfigMap

性能优化

# JVM 优化参数
JAVA_TOOL_OPTIONS="-XX:+UseZGC \
                  -XX:MaxGCPauseMillis=200 \
                  -XX:ParallelGCThreads=4 \
                  -XX:ConcGCThreads=2 \
                  -Xmx1024m -Xms1024m"

监控指标黄金四律

  1. 延时:请求响应时间(P95 < 500ms)
  2. 流量:每秒请求数(RPS)
  3. 错误率:HTTP错误率(< 0.1%)
  4. 饱和度:CPU使用率(< 70%)、内存使用率(< 80%)

部署演进路线:手动部署 → 脚本自动化 → CI/CD流水线 → Kubernetes编排 → GitOps工作流 → 全自动渐进式交付

通过实施本指南,部署效率可提升5-10倍,停机时间减少90%,平均故障恢复时间(MTTR)降至5分钟以下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值