SpringBoot 自动化部署实战:从环境搭建到 CI/CD 全流程

SpringBoot 自动化部署实战:从环境搭建到 CI/CD 全流程

一、自动化部署基础环境准备

1. 服务器环境配置

在开始部署前,需要先准备好服务器环境。以 Ubuntu 20.04 为例,基本环境配置步骤如下:

# 更新软件包列表sudo apt-get update# 安装JDK 11(SpringBoot 2.7+推荐JDK 11)sudo apt-get install openjdk-11-jdk# 安装Maven(用于项目构建)sudo apt-get install maven# 安装Git(用于代码拉取)sudo apt-get install git# 安装Nginx(用于反向代理)sudo apt-get install nginx# 配置防火墙sudo ufw allow 80/tcpsudo ufw allow 443/tcpsudo ufw allow 8080/tcp # SpringBoot默认端口sudo ufw enable

2. 项目结构优化

为了便于自动化部署,需要对 SpringBoot 项目结构进行优化:

your-project/├── src/│ ├── main/│ │ ├── java/│ │ ├── resources/│ │ │ ├── application.yml│ │ │ ├── application-prod.yml # 生产环境配置│ │ │ └── application-dev.yml # 开发环境配置│ └── test/├── pom.xml # Maven配置文件├── deploy/ # 部署相关脚本│ ├── build.sh # 构建脚本│ ├── start.sh # 启动脚本│ ├── stop.sh # 停止脚本│ └── deploy.yml # 部署配置└── .gitlab-ci.yml # CI/CD配置文件(以GitLab为例)

3. 日志规范设计

良好的日志规范对部署后的维护至关重要,在 application.yml 中添加如下配置:

logging: level: root: INFO com.yourcompany: DEBUG file: name: /var/log/your-project/your-project.log max-size: 10MB max-history: 7 pattern: console: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n" file: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n"

二、三种主流自动化部署方式实战

1. Shell 脚本部署方式

这是最基础的自动化部署方式,适合中小型项目。在项目根目录下创建 deploy 目录,添加以下脚本:

# deploy/build.sh#!/bin/bash# 构建项目mvn clean package -DskipTests -Pprod# 复制jar包到部署目录mkdir -p /opt/your-project/releasescp target/your-project-1.0.0.jar /opt/your-project/releases/your-project-latest.jar
# deploy/start.sh#!/bin/bash# 停止当前运行的进程./stop.sh# 创建日志目录mkdir -p /var/log/your-project# 启动新进程nohup java -jar \-XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m \-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/your-project/heapdump \-Dspring.config.location=/opt/your-project/application-prod.yml \/opt/your-project/releases/your-project-latest.jar > /var/log/your-project/start.log 2>&1 &# 输出进程IDecho $! > /opt/your-project/pid.txtecho "项目已启动,进程ID: $(cat /opt/your-project/pid.txt)"
# deploy/stop.sh#!/bin/bash# 停止进程if [ -f /opt/your-project/pid.txt ]; then PID=$(cat /opt/your-project/pid.txt) if [ -n "$PID" ]; then echo "正在停止进程: $PID" kill -15 $PID sleep 5 # 强制终止 if ps -p $PID > /dev/null; then echo "进程未正常停止,强制终止" kill -9 $PID fi fi rm -f /opt/your-project/pid.txtelse echo "未找到进程ID文件"fi

执行部署时,只需按顺序执行build.shstart.sh 脚本:

./deploy/build.sh./deploy/start.sh

2. Docker 容器化部署

Docker 部署方式具有更好的环境一致性和可移植性,首先在项目根目录添加 Dockerfile:

FROM openjdk:11-jdk-slimWORKDIR /app# 复制依赖和配置COPY pom.xml .COPY src/main/resources/application-prod.yml application.yml# 下载依赖(利用Docker缓存)RUN apt-get update && apt-get install -y maven && \ mvn dependency:go-offline -B# 复制项目代码COPY src ./src# 构建项目RUN mvn package -DskipTests -Pprod# 复制构建好的jar包COPY target/your-project-1.0.0.jar app.jar# 暴露端口EXPOSE 8080# 启动命令ENTRYPOINT ["java","-jar","app.jar"]

然后创建 docker-compose.yml 文件:

version: '3'services: your-project: build: . container_name: your-project restart: always ports: - "8080:8080" volumes: - /var/log/your-project:/var/log/your-project - /opt/your-project/conf:/app/conf environment: - SPRING_PROFILES_ACTIVE=prod healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"] interval: 30s timeout: 10s retries: 3

部署时只需执行:

docker-compose up -d

3. Kubernetes 集群部署

对于大型项目,推荐使用 Kubernetes 进行部署,首先创建 deployment.yaml:

apiVersion: apps/v1kind: Deploymentmetadata: name: your-project labels: app: your-projectspec: replicas: 3 selector: matchLabels: app: your-project template: metadata: labels: app: your-project spec: containers: - name: your-project image: your-registry/your-project:latest ports: - containerPort: 8080 livenessProbe: httpGet: path: /actuator/health port: 8080 initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: httpGet: path: /actuator/health port: 8080 initialDelaySeconds: 10 periodSeconds: 5 env: - name: SPRING_PROFILES_ACTIVE value: prod volumeMounts: - name: config-volume mountPath: /app/conf volumes: - name: config-volume configMap: name: your-project-config

创建 service.yaml:

apiVersion: v1kind: Servicemetadata: name: your-project-servicespec: type: NodePort ports: - port: 8080 targetPort: 8080 nodePort: 30080 selector: app: your-project

创建 configmap.yaml:

apiVersion: v1kind: ConfigMapmetadata: name: your-project-configdata: application-prod.yml: | spring: datasource: url: jdbc:mysql://mysql-service:3306/yourdb?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true username: youruser password: yourpassword redis: host: redis-service port: 6379

部署到 Kubernetes 集群:

kubectl apply -f deployment.yamlkubectl apply -f service.yamlkubectl apply -f configmap.yaml

三、CI/CD 流程搭建实战

1. GitLab CI/CD 配置

在项目根目录创建.gitlab-ci.yml 文件:

stages: - build - test - deployimage: maven:3.8.4-openjdk-11before_script: - echo "CI/CD流程开始" - mkdir -p .m2/repositorybuild_job: stage: build script: - mvn clean package -DskipTests artifacts: paths: - target/your-project-1.0.0.jar only: - maintest_job: stage: test script: - mvn test only: - maindeploy_to_staging: stage: deploy script: - echo "部署到测试环境" - scp target/your-project-1.0.0.jar staging-server:/opt/your-project/releases/ - ssh staging-server "cd /opt/your-project && ./deploy/start.sh" only: - developdeploy_to_production: stage: deploy script: - echo "部署到生产环境" - scp target/your-project-1.0.0.jar production-server:/opt/your-project/releases/ - ssh production-server "cd /opt/your-project && ./deploy/start.sh" only: - main when: manual # 生产环境部署需要手动确认

2. Jenkins CI/CD 配置

在 Jenkins 中创建 Pipeline 项目,Jenkinsfile 内容如下:

pipeline { agent any tools { maven 'Maven 3.8.4' jdk 'Java 11' } stages { stage('Build') { steps { sh 'mvn clean package -DskipTests' } artifacts { archivesArtifacts 'target/your-project-1.0.0.jar' } } stage('Test') { steps { sh 'mvn test' } } stage('Deploy to Staging') { when { branch 'develop' } steps { sh """ scp target/your-project-1.0.0.jar staging-server:/opt/your-project/releases/ ssh staging-server "cd /opt/your-project && ./deploy/start.sh" """ } } stage('Deploy to Production') { when { branch 'main' } steps { input message: '确认部署到生产环境?', ok: '部署' sh """ scp target/your-project-1.0.0.jar production-server:/opt/your-project/releases/ ssh production-server "cd /opt/your-project && ./deploy/start.sh" """ } } } post { success { slackSend channel: '#deploy-notifications', message: "部署成功: ${env.JOB_NAME} #${env.BUILD_NUMBER}" } failure { slackSend channel: '#deploy-notifications', message: "部署失败: ${env.JOB_NAME} #${env.BUILD_NUMBER}" } }}

3. 蓝绿部署与金丝雀发布

蓝绿部署实现

在 Kubernetes 中实现蓝绿部署,只需修改 deployment.yaml 的标签和版本号:

apiVersion: apps/v1kind: Deploymentmetadata: name: your-project-v1 labels: app: your-project version: v1spec: # 配置不变...---apiVersion: apps/v1kind: Servicemetadata: name: your-projectspec: # 服务选择器根据当前活跃版本调整 selector: app: your-project version: v1

升级时创建新的 deployment 并更新服务选择器:

apiVersion: apps/v1kind: Deploymentmetadata: name: your-project-v2 labels: app: your-project version: v2spec: # 新版本配置...
金丝雀发布实现

使用 Istio 服务网格实现金丝雀发布,创建 virtualservice.yaml:

apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata: name: your-projectspec: hosts: - your-project.com http: - route: - destination: host: your-project-v1 port: number: 8080 weight: 90 - destination: host: your-project-v2 port: number: 8080 weight: 10

四、部署后的监控与问题排查

1. 系统监控配置

使用 Prometheus 和 Grafana 搭建监控系统,在 SpringBoot 项目中添加监控依赖:

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-prometheus</artifactId></dependency>

配置 application.yml:

management: endpoints: web: exposure: include: "*" metrics: export: prometheus: enabled: true step: 10s endpoint: health: show-details: always

在 Prometheus 配置中添加监控目标:

- job_name: 'your-project' metrics_path: '/actuator/prometheus' static_configs: - targets: ['your-project-server:8080']

2. 日志收集与分析

使用 ELK Stack 收集日志,在 SpringBoot 项目中添加 Logstash 依赖:

<dependency> <groupId>net.logstash.logback</groupId> <artifactId>logstash-logback-encoder</artifactId> <version>7.2.0</version></dependency>

添加 logback-spring.xml 配置:

<configuration> <appender name="LOGSTASH" > <destination>logstash-server:5044</destination> <encoder /> </appender> <root level="INFO"> <appender-ref ref="LOGSTASH" /> </root></configuration>

3. 常见问题排查命令

# 查看Java进程ps -ef | grep java# 查看CPU和内存使用情况top -p <PID># 查看JVM堆内存使用jmap -heap <PID># 查看线程状态jstack <PID> | grep -A 10 RUNNABLE# 查看应用日志tail -f /var/log/your-project/your-project.log# 查看Kubernetes pod状态kubectl get pods -n your-namespace# 查看容器日志kubectl logs your-pod-name -n your-namespace

五、实战案例:高并发系统部署优化

1. 案例背景

某电商平台订单系统,采用 SpringBoot 开发,日均订单量 100 万 +,高峰期 QPS 达 5000+,部署后出现以下问题:

  • 高峰期 CPU 使用率持续 100%

  • 偶尔出现 GC 超时导致的请求卡顿

  • 数据库连接池经常达到最大连接数

2. 优化方案

JVM 参数优化
java -jar \-XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=1024m \-XX:+UseG1GC -XX:G1HeapRegionSize=16m \-XX:InitialHeapSize=4g -XX:MaxHeapSize=8g \-XX:MaxTenuringThreshold=15 \-XX:+ExplicitGCInvokesConcurrent \-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/your-project/heapdump \-XX:ErrorFile=/opt/your-project/hs_err_pid%p.log \-Dspring.config.location=/opt/your-project/application-prod.yml \/opt/your-project/releases/your-project-latest.jar
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

半抹灯芯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值