SpringBoot 项目部署与运维——从打包到上线全流程

开发写得再好,部署不上线等于零。这一篇讲 SpringBoot 项目从打包到上线的完整流程------包含 Linux 环境搭建、Docker 容器化部署、Nginx 反向代理、日志排查。

一、项目打包

1. Maven 打包

xml 复制代码
<!-- pom.xml 确保有 spring-boot-maven-plugin -->
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>
bash 复制代码
# 跳过测试打包(省时间)
mvn clean package -DskipTests

# 打包后在 target/ 目录下生成 jar 文件
# seckill-system-0.0.1-SNAPSHOT.jar

2. 配置文件外部化

不同环境用不同配置,不要在代码里改:

bash 复制代码
# 打包时指定环境
mvn clean package -DskipTests -Pprod

# 或者在启动时指定
java -jar app.jar --spring.profiles.active=prod

对应的配置文件:

复制代码
application.yml          # 公共配置
application-dev.yml      # 开发环境
application-prod.yml     # 生产环境

生产环境的配置(数据库密码、Redis 密码)不要写死在代码里,用环境变量:

yaml 复制代码
# application-prod.yml
spring:
  datasource:
    url: jdbc:mysql://${DB_HOST}:${DB_PORT}/${DB_NAME}?useUnicode=true&characterEncoding=utf-8
    username: ${DB_USER}
    password: ${DB_PASSWORD}
bash 复制代码
# 启动时传入环境变量
java -jar app.jar \
  -DDB_HOST=192.168.1.100 \
  -DDB_PORT=3306 \
  -DDB_NAME=seckill_db \
  -DDB_USER=root \
  -DDB_PASSWORD=your_password

二、Linux 部署

1. 安装 Java 环境

bash 复制代码
# Ubuntu/Debian
sudo apt update
sudo apt install openjdk-17-jdk -y
java -version

# CentOS/RHEL
sudo yum install java-17-openjdk -y

2. 上传并启动

bash 复制代码
# 上传 jar 到服务器
scp target/app.jar root@你的IP:/opt/app/

# 启动(测试用)
cd /opt/app/
java -jar app.jar --spring.profiles.active=prod &

# 查看日志
tail -f nohup.out

3. 用脚本管理(推荐)

bash 复制代码
#!/bin/bash
# startup.sh

APP_NAME="app.jar"
APP_PATH="/opt/app/$APP_NAME"
LOG_PATH="/opt/app/logs"

case "$1" in
    start)
        echo "启动 $APP_NAME ..."
        nohup java -jar $APP_PATH \
            --spring.profiles.active=prod \
            > $LOG_PATH/startup.log 2>&1 &
        echo "启动完成,PID: $!"
        ;;
    stop)
        echo "停止 $APP_NAME ..."
        PID=$(ps aux | grep $APP_NAME | grep -v grep | awk '{print $2}')
        if [ -n "$PID" ]; then
            kill -15 $PID
            echo "已停止"
        else
            echo "未运行"
        fi
        ;;
    restart)
        $0 stop
        sleep 3
        $0 start
        ;;
    logs)
        tail -f $LOG_PATH/startup.log
        ;;
    *)
        echo "用法: $0 {start|stop|restart|logs}"
        ;;
esac
bash 复制代码
# 使用
chmod +x startup.sh
./startup.sh start     # 启动
./startup.sh stop      # 停止
./startup.sh restart   # 重启
./startup.sh logs      # 看日志

4. 注册为系统服务

bash 复制代码
# /etc/systemd/system/myapp.service
[Unit]
Description=SpringBoot App
After=network.target

[Service]
Type=simple
User=root
WorkingDirectory=/opt/app
ExecStart=/usr/bin/java -jar /opt/app/app.jar --spring.profiles.active=prod
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target
bash 复制代码
sudo systemctl daemon-reload
sudo systemctl enable myapp    # 开机自启
sudo systemctl start myapp     # 启动
sudo systemctl status myapp    # 查看状态
sudo journalctl -u myapp -f    # 看日志

三、Docker 容器化部署

1. 编写 Dockerfile

dockerfile 复制代码
# Dockerfile
FROM openjdk:17-jdk-alpine

# 维护者信息
LABEL maintainer="zhangzheng@example.com"

# 创建工作目录
WORKDIR /app

# 复制 jar 包
COPY target/app.jar app.jar

# 暴露端口(根据你的项目改)
EXPOSE 9090

# 启动命令
ENTRYPOINT ["java", "-jar", "app.jar", "--spring.profiles.active=prod"]

2. 构建镜像并运行

bash 复制代码
# 构建镜像
docker build -t seckill-system:v1.0 .

# 查看镜像
docker images

# 运行容器
docker run -d \
  --name seckill-app \
  -p 9090:9090 \
  -e DB_HOST=192.168.1.100 \
  -e DB_PORT=3306 \
  -e DB_NAME=seckill_db \
  -e DB_USER=root \
  -e DB_PASSWORD=123456 \
  -v /opt/app/logs:/app/logs \
  --restart=always \
  seckill-system:v1.0

# 查看运行状态
docker ps
docker logs -f seckill-app

3. 用 Docker Compose 管理多容器

如果你的项目依赖 Redis、MySQL、RabbitMQ,用 Compose 一键启动:

yaml 复制代码
# docker-compose.yml
version: '3.8'

services:
  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: 123456
      MYSQL_DATABASE: seckill_db
    ports:
      - "3306:3306"
    volumes:
      - mysql_data:/var/lib/mysql
    restart: always

  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    restart: always

  app:
    build: .
    ports:
      - "9090:9090"
    environment:
      DB_HOST: mysql
      DB_PORT: 3306
      DB_NAME: seckill_db
      DB_USER: root
      DB_PASSWORD: 123456
      SPRING_REDIS_HOST: redis
    depends_on:
      - mysql
      - redis
    restart: always

volumes:
  mysql_data:
bash 复制代码
# 一键启动所有服务
docker-compose up -d

# 查看所有容器
docker-compose ps

# 停止
docker-compose down

四、Nginx 反向代理

1. 为什么要加 Nginx

复制代码
不用 Nginx:
  用户 → http://ip:9090 直接访问(暴露端口号,不安全)

用 Nginx:
  用户 → http://api.example.com(80端口)
              ↓
         Nginx → http://localhost:9090(反向代理)

好处:隐藏真实端口、支持 HTTPS、负载均衡、静态文件分离。

2. 配置 Nginx

nginx 复制代码
# /etc/nginx/conf.d/seckill.conf
server {
    listen 80;
    server_name api.example.com;  # 你的域名

    # 反向代理到 SpringBoot
    location / {
        proxy_pass http://127.0.0.1:9090;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # 静态资源(如果有)
    location /static/ {
        root /opt/app/;
        expires 7d;
    }
}
bash 复制代码
# 检查配置
nginx -t

# 重新加载
nginx -s reload

3. 配置 HTTPS(免费证书)

bash 复制代码
# 安装 certbot(Let's Encrypt 免费证书)
sudo apt install certbot python3-certbot-nginx -y

# 获取证书并自动配置 Nginx
sudo certbot --nginx -d api.example.com

# 自动续期(证书有效期90天)
sudo certbot renew --dry-run

配置完成后,Nginx 自动生成 HTTPS 配置,访问 https://api.example.com 即可。

五、日志排查

1. SpringBoot 日志配置

yaml 复制代码
# application.yml
logging:
  level:
    root: INFO
    com.zhang.seckill: DEBUG  # 自己的包用 DEBUG
  file:
    path: /opt/app/logs
    name: ${logging.file.path}/app.log
  logback:
    rolling policy:
      max-history: 7          # 保留7天
      max-file-size: 100MB    # 每个文件最大100MB

2. 常见问题排查

bash 复制代码
# 查看应用是否在运行
ps aux | grep java
netstat -tlnp | grep 9090

# 查看日志
tail -200f /opt/app/logs/app.log

# 查看磁盘(日志写满了会出问题)
df -h

# 查看内存
free -m

# 查看 CPU
top

# 端口占用
lsof -i:9090

3. 健康检查

xml 复制代码
<!-- 引入 Actuator -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
yaml 复制代码
# 暴露所有端点
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics

访问 http://你的IP:9090/actuator/health 查看应用状态。

六、部署检查清单

上线前逐项检查:

复制代码
[x] 数据库连接配置改成环境变量
[x] Redis、MQ 等中间件地址改成环境变量
[x] 日志路径可写
[x] 端口有没有被占用
[x] 防火墙有没有开放端口
[x] 内存够不够(java -jar 默认堆大小)
[x] 是否配置了开机自启

一个原则: 生产环境的 IP、密码、密钥永远不要写在代码或配置文件里,全部用环境变量或配置中心。


💡 觉得有用的话,点赞 + 关注【张老师技术栈】吧!每周更新 Java/Python/爬虫 实战干货,不让你白来。