开发写得再好,部署不上线等于零。这一篇讲 SpringBoot 项目从打包到上线的完整流程——包含 Linux 环境搭建、Docker 容器化部署、Nginx 反向代理、日志排查。
一、项目打包
1. Maven 打包
<!-- pom.xml 确保有 spring-boot-maven-plugin -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
# 跳过测试打包(省时间)
mvn clean package -DskipTests
# 打包后在 target/ 目录下生成 jar 文件
# seckill-system-0.0.1-SNAPSHOT.jar
2. 配置文件外部化
不同环境用不同配置,不要在代码里改:
# 打包时指定环境
mvn clean package -DskipTests -Pprod
# 或者在启动时指定
java -jar app.jar --spring.profiles.active=prod
对应的配置文件:
application.yml # 公共配置
application-dev.yml # 开发环境
application-prod.yml # 生产环境
生产环境的配置(数据库密码、Redis 密码)不要写死在代码里,用环境变量:
# 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}
# 启动时传入环境变量
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 环境
# Ubuntu/Debian
sudo apt update
sudo apt install openjdk-17-jdk -y
java -version
# CentOS/RHEL
sudo yum install java-17-openjdk -y
2. 上传并启动
# 上传 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. 用脚本管理(推荐)
#!/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
# 使用
chmod +x startup.sh
./startup.sh start # 启动
./startup.sh stop # 停止
./startup.sh restart # 重启
./startup.sh logs # 看日志
4. 注册为系统服务
# /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
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
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. 构建镜像并运行
# 构建镜像
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 一键启动:
# 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:
# 一键启动所有服务
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
# /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;
}
}
# 检查配置
nginx -t
# 重新加载
nginx -s reload
3. 配置 HTTPS(免费证书)
# 安装 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 日志配置
# 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. 常见问题排查
# 查看应用是否在运行
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. 健康检查
<!-- 引入 Actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
# 暴露所有端点
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/爬虫 实战干货,不让你白来。
343

被折叠的 条评论
为什么被折叠?



