生产环境部署详细指南
📋 目录
部署前准备
1. 服务器环境检查清单
# 检查 Java 版本(需要 Java 21)
java -version
# 检查 Maven 版本(需要 3.6+)
mvn -version
# 检查 Node.js 版本(需要 18+,仅构建时需要)
node -v
npm -v
# 检查 MySQL 版本(需要 8.0+)
mysql --version
# 检查系统资源
free -h # Linux
systeminfo # Windows
df -h # 磁盘空间
2. 创建部署用户(推荐)
# Linux 示例
sudo useradd -m -s /bin/bash appuser
sudo passwd appuser
sudo mkdir -p /opt/jxcapp
sudo chown -R appuser:appuser /opt/jxcapp
3. 防火墙配置
# 开放必要端口
# 8080: 应用端口
# 3306: MySQL 端口(如果数据库在同一服务器)
sudo ufw allow 8080/tcp
sudo ufw allow 3306/tcp
sudo ufw reload
环境要求
最低配置
- CPU: 2 核心
- 内存: 4GB RAM
- 磁盘: 20GB 可用空间
- 操作系统: Linux (Ubuntu 20.04+, CentOS 7+), Windows Server 2016+
推荐配置
- CPU: 4+ 核心
- 内存: 8GB+ RAM
- 磁盘: 50GB+ SSD
- 操作系统: Linux (Ubuntu 22.04 LTS, CentOS 8+)
软件依赖
| 软件 | 版本要求 | 说明 |
|---|---|---|
| Java | 21+ | 运行环境必需 |
| Maven | 3.6+ | 构建时必需 |
| Node.js | 18+ | 仅构建前端时必需 |
| MySQL | 8.0+ | 数据库 |
| Nginx | 1.18+ | 前后端分离部署时可选 |
部署方式选择
方式一:单 JAR 部署
适用场景:
- 中小型应用
- 单服务器部署
- 简化运维
- 快速部署
优点:
- 部署简单,只需一个 JAR 文件
- 无需配置 Nginx
- 前后端版本一致
- 易于版本管理
缺点:
- 前后端耦合,无法独立扩展
- 静态资源由 Spring Boot 提供,性能略低
方式二:前后端分离部署
适用场景:
- 大型应用
- 需要独立扩展前后端
- 需要 CDN 加速
- 多环境部署
优点:
- 前后端可独立扩展
- 静态资源可由 CDN 或 Nginx 高效提供
- 更灵活的负载均衡
缺点:
- 配置相对复杂
- 需要配置反向代理
- 需要管理多个服务
方式一:单 JAR 部署(推荐)
步骤 1: 准备生产环境配置文件
创建 backend/src/main/resources/application-prod.yml:
spring:
application:
name: jxcapp
datasource:
url: jdbc:mysql://${DB_HOST:localhost}:${DB_PORT:3306}/${DB_NAME:jxcapp}?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=Asia/Shanghai&autoReconnect=true&failOverReadOnly=false&maxReconnects=3&initialTimeout=2&connectTimeout=60000&socketTimeout=60000&useServerPrepStmts=true&cachePrepStmts=true&prepStmtCacheSize=250&prepStmtCacheSqlLimit=2048
username: ${DB_USER:root}
password: ${DB_PASSWORD}
driver-class-name: com.mysql.cj.jdbc.Driver
hikari:
minimum-idle: 5
maximum-pool-size: 20
connection-timeout: 60000
idle-timeout: 600000
max-lifetime: 1800000
leak-detection-threshold: 60000
pool-name: JxcHikariPool
jpa:
hibernate:
ddl-auto: validate # 生产环境使用 validate,不使用 update
show-sql: false # 生产环境关闭 SQL 日志
open-in-view: false
properties:
hibernate:
format_sql: false
connection:
provider_disables_autocommit: false
transaction:
coordinator_class: jdbc
server:
port: ${SERVER_PORT:8080}
servlet:
context-path: /
compression:
enabled: true
mime-types: application/json,application/xml,text/html,text/xml,text/plain,application/javascript,text/css
min-response-size: 1024
jwt:
secret: ${JWT_SECRET} # 必须设置强密钥
expiration: ${JWT_EXPIRATION:86400000}
logging:
level:
root: INFO
com.jxc: INFO
org.springframework.web: WARN
org.springframework.security: WARN
org.hibernate: WARN
file:
name: /var/log/jxcapp/application.log
max-size: 10MB
max-history: 30
pattern:
file: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"
console: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"
步骤 2: 配置前端生产环境变量
创建 frontend/.env.production:
# 单 JAR 部署时,API 使用相对路径
VITE_API_URL=/api
步骤 3: 构建应用
# 进入后端目录
cd backend
# 清理并构建(Maven 会自动构建前端)
mvn clean package -DskipTests -Pprod
# 如果构建失败,可以分步执行:
# 1. 手动构建前端
cd ../frontend
npm install --production=false
npm run build
# 2. 复制前端资源到后端
# Linux/Mac:
cp -r dist/* ../backend/src/main/resources/static/
# Windows:
xcopy /E /I /Y dist\* ..\backend\src\main\resources\static\
# 3. 只构建后端
cd ../backend
mvn clean package -DskipTests
步骤 4: 部署 JAR 文件
# 创建应用目录
sudo mkdir -p /opt/jxcapp
sudo mkdir -p /var/log/jxcapp
sudo chown -R appuser:appuser /opt/jxcapp
sudo chown -R appuser:appuser /var/log/jxcapp
# 复制 JAR 文件
cp backend/target/jxcapp-1.0.0.jar /opt/jxcapp/
# 创建启动脚本
cat > /opt/jxcapp/start.sh << 'EOF'
#!/bin/bash
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk
export PATH=$JAVA_HOME/bin:$PATH
# 设置 JVM 参数
JVM_OPTS="-Xms512m -Xmx2048m"
JVM_OPTS="$JVM_OPTS -XX:+UseG1GC"
JVM_OPTS="$JVM_OPTS -XX:MaxGCPauseMillis=200"
JVM_OPTS="$JVM_OPTS -XX:+HeapDumpOnOutOfMemoryError"
JVM_OPTS="$JVM_OPTS -XX:HeapDumpPath=/var/log/jxcapp/heapdump.hprof"
JVM_OPTS="$JVM_OPTS -Dspring.profiles.active=prod"
# 设置环境变量
export DB_HOST=localhost
export DB_PORT=3306
export DB_NAME=jxcapp
export DB_USER=jxcapp_user
export DB_PASSWORD=your_secure_password
export JWT_SECRET=your_very_long_and_secure_jwt_secret_key_at_least_32_characters
export SERVER_PORT=8080
# 启动应用
java $JVM_OPTS -jar /opt/jxcapp/jxcapp-1.0.0.jar
EOF
chmod +x /opt/jxcapp/start.sh
步骤 5: 配置 Systemd 服务(Linux)
创建 /etc/systemd/system/jxcapp.service:
[Unit]
Description=JXC Application
After=network.target mysql.service
[Service]
Type=simple
User=appuser
Group=appuser
WorkingDirectory=/opt/jxcapp
ExecStart=/opt/jxcapp/start.sh
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
SyslogIdentifier=jxcapp
# 环境变量
Environment="JAVA_HOME=/usr/lib/jvm/java-21-openjdk"
Environment="DB_HOST=localhost"
Environment="DB_PORT=3306"
Environment="DB_NAME=jxcapp"
Environment="DB_USER=jxcapp_user"
Environment="DB_PASSWORD=your_secure_password"
Environment="JWT_SECRET=your_very_long_and_secure_jwt_secret_key_at_least_32_characters"
Environment="SERVER_PORT=8080"
Environment="SPRING_PROFILES_ACTIVE=prod"
# 资源限制
LimitNOFILE=65536
LimitNPROC=4096
[Install]
WantedBy=multi-user.target
启动服务:
sudo systemctl daemon-reload
sudo systemctl enable jxcapp
sudo systemctl start jxcapp
sudo systemctl status jxcapp
步骤 6: 验证部署
# 检查服务状态
sudo systemctl status jxcapp
# 查看日志
sudo journalctl -u jxcapp -f
# 或
tail -f /var/log/jxcapp/application.log
# 测试应用
curl http://localhost:8080/api/auth/login -X POST \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin123"}'
方式二:前后端分离部署
前端部署
步骤 1: 构建前端
cd frontend
# 创建生产环境配置
cat > .env.production << 'EOF'
VITE_API_URL=https://api.yourdomain.com
EOF
# 安装依赖并构建
npm install --production=false
npm run build:prod
# 构建产物在 frontend/dist 目录
步骤 2: 配置 Nginx
创建 /etc/nginx/sites-available/jxcapp:
# 前端服务器配置
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
# 重定向到 HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name yourdomain.com www.yourdomain.com;
# SSL 证书配置
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# 前端静态文件
root /var/www/jxcapp/frontend/dist;
index index.html;
# Gzip 压缩
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/json application/javascript;
# 静态资源缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
# API 代理
location /api {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
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;
proxy_cache_bypass $http_upgrade;
proxy_read_timeout 300s;
proxy_connect_timeout 75s;
}
# 前端路由支持(Vue Router history 模式)
location / {
try_files $uri $uri/ /index.html;
add_header Cache-Control "no-cache, no-store, must-revalidate";
}
# 安全头
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
# 日志
access_log /var/log/nginx/jxcapp-access.log;
error_log /var/log/nginx/jxcapp-error.log;
}
步骤 3: 部署前端文件
# 创建目录
sudo mkdir -p /var/www/jxcapp/frontend
sudo chown -R www-data:www-data /var/www/jxcapp/frontend
# 复制构建产物
sudo cp -r frontend/dist/* /var/www/jxcapp/frontend/
# 启用站点
sudo ln -s /etc/nginx/sites-available/jxcapp /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
后端部署
步骤 1: 构建后端
cd backend
mvn clean package -DskipTests -Pprod
步骤 2: 配置后端 Nginx(可选,用于负载均衡)
创建 /etc/nginx/sites-available/jxcapp-api:
# 后端 API 服务器配置
upstream jxcapp_backend {
least_conn;
server localhost:8080 max_fails=3 fail_timeout=30s;
# 如果有多个实例,可以添加更多服务器
# server localhost:8081 max_fails=3 fail_timeout=30s;
}
server {
listen 80;
server_name api.yourdomain.com;
# 重定向到 HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name api.yourdomain.com;
# SSL 证书配置
ssl_certificate /etc/letsencrypt/live/api.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.yourdomain.com/privkey.pem;
# API 代理
location / {
proxy_pass http://jxcapp_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
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;
proxy_cache_bypass $http_upgrade;
proxy_read_timeout 300s;
proxy_connect_timeout 75s;
# 限制请求大小
client_max_body_size 10M;
}
# 健康检查
location /actuator/health {
proxy_pass http://jxcapp_backend;
access_log off;
}
}
步骤 3: 部署后端 JAR
参考方式一:单 JAR 部署的步骤 4-6,但注意:
- 修改 CORS 配置,允许前端域名访问
- 确保后端只监听
localhost:8080(通过 Nginx 对外提供服务)
数据库配置与初始化
步骤 1: 创建数据库和用户
-- 登录 MySQL
mysql -u root -p
-- 创建数据库
CREATE DATABASE jxcapp CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 创建用户并授权
CREATE USER 'jxcapp_user'@'localhost' IDENTIFIED BY 'your_secure_password';
GRANT ALL PRIVILEGES ON jxcapp.* TO 'jxcapp_user'@'localhost';
FLUSH PRIVILEGES;
-- 如果数据库在远程服务器
CREATE USER 'jxcapp_user'@'%' IDENTIFIED BY 'your_secure_password';
GRANT ALL PRIVILEGES ON jxcapp.* TO 'jxcapp_user'@'%';
FLUSH PRIVILEGES;
步骤 2: 执行初始化脚本
# 执行数据库初始化脚本
mysql -u jxcapp_user -p jxcapp < backend/src/main/resources/db/init.sql
步骤 3: 验证数据库连接
# 测试连接
mysql -u jxcapp_user -p -h localhost jxcapp -e "SHOW TABLES;"
步骤 4: 数据库优化配置
编辑 MySQL 配置文件 /etc/mysql/mysql.conf.d/mysqld.cnf:
[mysqld]
# 字符集
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
# 连接数
max_connections=200
max_connect_errors=10
# 缓冲区
innodb_buffer_pool_size=1G
innodb_log_file_size=256M
innodb_flush_log_at_trx_commit=2
innodb_flush_method=O_DIRECT
# 查询缓存(MySQL 8.0 已移除,无需配置)
# query_cache_size=0
# query_cache_type=0
# 慢查询日志
slow_query_log=1
slow_query_log_file=/var/log/mysql/slow-query.log
long_query_time=2
# 二进制日志(用于主从复制和恢复)
log_bin=/var/log/mysql/mysql-bin.log
expire_logs_days=7
max_binlog_size=100M
重启 MySQL:
sudo systemctl restart mysql
环境变量配置
推荐使用环境变量文件
创建 /opt/jxcapp/.env:
# 数据库配置
DB_HOST=localhost
DB_PORT=3306
DB_NAME=jxcapp
DB_USER=jxcapp_user
DB_PASSWORD=your_secure_password
# 应用配置
SERVER_PORT=8080
SPRING_PROFILES_ACTIVE=prod
# JWT 配置
JWT_SECRET=your_very_long_and_secure_jwt_secret_key_at_least_32_characters
JWT_EXPIRATION=86400000
# 日志配置
LOG_DIR=/var/log/jxcapp
修改启动脚本加载环境变量:
# 在 start.sh 中添加
source /opt/jxcapp/.env
安全提示:
- 使用
chmod 600 /opt/jxcapp/.env限制文件权限 - 不要将
.env文件提交到版本控制
安全配置
1. JWT Secret 生成
# 生成强随机密钥(64 字符)
openssl rand -hex 32
2. 数据库密码策略
- 使用强密码(至少 16 字符,包含大小写字母、数字、特殊字符)
- 定期更换密码
- 使用不同的密码用于不同环境
3. 防火墙规则
# 只允许必要的端口
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
4. SSL/TLS 证书(使用 Let's Encrypt)
# 安装 Certbot
sudo apt-get update
sudo apt-get install certbot python3-certbot-nginx
# 获取证书
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
# 自动续期
sudo certbot renew --dry-run
5. 后端安全配置
修改 SecurityConfig.java 中的 CORS 配置(生产环境):
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
// 生产环境只允许特定域名
configuration.setAllowedOrigins(List.of(
"https://yourdomain.com",
"https://www.yourdomain.com"
));
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"));
configuration.setAllowedHeaders(Arrays.asList("*"));
configuration.setAllowCredentials(true);
configuration.setMaxAge(3600L);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
6. 禁用开发工具
确保生产环境 JAR 中不包含:
- Spring Boot DevTools
- 调试日志
- 开发配置文件
性能优化
1. JVM 参数优化
# 生产环境推荐 JVM 参数
JVM_OPTS="-Xms2g -Xmx4g"
JVM_OPTS="$JVM_OPTS -XX:+UseG1GC"
JVM_OPTS="$JVM_OPTS -XX:MaxGCPauseMillis=200"
JVM_OPTS="$JVM_OPTS -XX:+HeapDumpOnOutOfMemoryError"
JVM_OPTS="$JVM_OPTS -XX:HeapDumpPath=/var/log/jxcapp/heapdump.hprof"
JVM_OPTS="$JVM_OPTS -XX:+UseStringDeduplication"
JVM_OPTS="$JVM_OPTS -XX:+OptimizeStringConcat"
JVM_OPTS="$JVM_OPTS -Djava.awt.headless=true"
JVM_OPTS="$JVM_OPTS -Dfile.encoding=UTF-8"
2. 数据库连接池优化
根据实际负载调整 application-prod.yml:
spring:
datasource:
hikari:
minimum-idle: 10 # 根据并发量调整
maximum-pool-size: 50 # 根据数据库服务器性能调整
connection-timeout: 30000
idle-timeout: 600000
max-lifetime: 1800000
3. Nginx 性能优化
# 在 /etc/nginx/nginx.conf 中
worker_processes auto;
worker_connections 1024;
# 启用缓存
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=api_cache:10m max_size=1g inactive=60m;
# 在 server 块中使用缓存
proxy_cache api_cache;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
4. 前端资源优化
- 启用 Gzip 压缩(已在 Nginx 配置中)
- 使用 CDN 加速静态资源
- 配置浏览器缓存策略
监控与日志
1. 应用日志
日志文件位置:/var/log/jxcapp/application.log
# 查看实时日志
tail -f /var/log/jxcapp/application.log
# 查看错误日志
grep ERROR /var/log/jxcapp/application.log
# 日志轮转(使用 logrotate)
sudo cat > /etc/logrotate.d/jxcapp << 'EOF'
/var/log/jxcapp/*.log {
daily
rotate 30
compress
delaycompress
notifempty
create 0644 appuser appuser
sharedscripts
postrotate
systemctl reload jxcapp > /dev/null 2>&1 || true
endscript
}
EOF
2. 系统监控
# 安装监控工具
sudo apt-get install htop iotop nethogs
# 监控应用进程
ps aux | grep jxcapp
# 监控资源使用
htop
3. 健康检查端点
Spring Boot Actuator 配置(可选):
在 pom.xml 中添加:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
在 application-prod.yml 中配置:
management:
endpoints:
web:
exposure:
include: health,info,metrics
endpoint:
health:
show-details: when-authorized
访问:http://localhost:8080/actuator/health
常见问题与解决方案
问题 1: Maven 构建失败 - 前端构建错误
症状:
[ERROR] npm ERR! code ELIFECYCLE
[ERROR] npm ERR! errno 1
解决方案:
- 检查 Node.js 版本:
node -v # 需要 18+
- 手动构建前端:
cd frontend
rm -rf node_modules package-lock.json
npm install
npm run build
- 跳过前端构建,手动复制:
# 构建前端
cd frontend && npm run build
# 复制到后端
cp -r dist/* ../backend/src/main/resources/static/
# 只构建后端
cd ../backend
mvn clean package -DskipTests
问题 2: 数据库连接失败
症状:
Communications link failure
The last packet sent successfully to the server was X milliseconds ago
解决方案:
- 检查数据库服务:
sudo systemctl status mysql
- 检查网络连接:
telnet localhost 3306
# 或
nc -zv localhost 3306
- 检查数据库用户权限:
SHOW GRANTS FOR 'jxcapp_user'@'localhost';
- 检查防火墙:
sudo ufw status
- 增加连接超时时间: 在
application-prod.yml中:
spring:
datasource:
hikari:
connection-timeout: 60000
问题 3: 静态资源 404 错误
症状: 浏览器控制台显示 JS/CSS 文件 404
解决方案:
- 检查静态资源是否存在:
ls -la backend/src/main/resources/static/
- 确保执行了完整构建:
mvn clean package
检查 WebMvcConfig 配置: 确保
WebMvcConfig.java中配置了静态资源映射检查 SecurityConfig: 确保
SecurityConfig.java中允许静态资源访问
问题 4: 前端路由 404(单页应用)
症状: 直接访问 /users 等路由返回 404
解决方案:
- 单 JAR 部署: 确保
WebMvcConfig.java中配置了:
registry.addViewController("/").setViewName("forward:/index.html");
- 前后端分离部署: 确保 Nginx 配置了:
location / {
try_files $uri $uri/ /index.html;
}
问题 5: CORS 跨域错误
症状:
Access to XMLHttpRequest at '...' from origin '...' has been blocked by CORS policy
解决方案:
检查 SecurityConfig 中的 CORS 配置: 确保生产环境域名已添加到允许列表
检查 Nginx 配置: 如果使用 Nginx,确保代理配置正确
临时测试(仅开发环境):
configuration.setAllowedOrigins(Arrays.asList("*")); // 仅用于测试
问题 6: JWT Token 无效
症状: API 请求返回 401 Unauthorized
解决方案:
检查 JWT Secret: 确保生产环境使用了正确的 JWT Secret
检查 Token 过期时间:
jwt:
expiration: 86400000 # 24 小时
检查前端 Token 存储: 确保 Token 正确存储在 localStorage 或 cookie 中
查看后端日志:
grep "JWT" /var/log/jxcapp/application.log
问题 7: 内存溢出 (OutOfMemoryError)
症状:
java.lang.OutOfMemoryError: Java heap space
解决方案:
- 增加堆内存:
JVM_OPTS="-Xms2g -Xmx4g"
- 启用堆转储:
JVM_OPTS="$JVM_OPTS -XX:+HeapDumpOnOutOfMemoryError"
JVM_OPTS="$JVM_OPTS -XX:HeapDumpPath=/var/log/jxcapp/heapdump.hprof"
分析堆转储: 使用 Eclipse MAT 或 VisualVM 分析内存泄漏
检查数据库连接泄漏:
spring:
datasource:
hikari:
leak-detection-threshold: 60000
问题 8: 端口被占用
症状:
Port 8080 is already in use
解决方案:
- 查找占用端口的进程:
# Linux
sudo lsof -i :8080
# 或
sudo netstat -tulpn | grep 8080
# Windows
netstat -ano | findstr :8080
- 停止占用进程:
sudo kill -9 <PID>
- 更改应用端口:
server:
port: 8081
问题 9: 数据库表不存在
症状:
Table 'jxcapp.xxx' doesn't exist
解决方案:
- 执行初始化脚本:
mysql -u jxcapp_user -p jxcapp < backend/src/main/resources/db/init.sql
- 检查 Hibernate 配置:
spring:
jpa:
hibernate:
ddl-auto: validate # 生产环境使用 validate
- 手动创建表: 检查
init.sql脚本是否完整
问题 10: 启动缓慢
症状: 应用启动时间超过 1 分钟
解决方案:
检查数据库连接: 确保数据库服务器响应快速
优化 JVM 启动参数:
JVM_OPTS="$JVM_OPTS -XX:+TieredCompilation"
JVM_OPTS="$JVM_OPTS -XX:TieredStopAtLevel=1"
- 禁用不必要的自动配置:
@SpringBootApplication(exclude = {
// 排除不需要的自动配置
})
故障排查
排查步骤
- 检查服务状态:
sudo systemctl status jxcapp
- 查看日志:
# 应用日志
tail -f /var/log/jxcapp/application.log
# 系统日志
sudo journalctl -u jxcapp -f
# Nginx 日志(如果使用)
tail -f /var/log/nginx/jxcapp-error.log
- 检查资源使用:
# CPU 和内存
top
htop
# 磁盘空间
df -h
# 网络连接
netstat -tulpn
- 测试数据库连接:
mysql -u jxcapp_user -p -h localhost jxcapp -e "SELECT 1;"
- 测试 API 端点:
curl http://localhost:8080/api/auth/login -X POST \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin123"}'
常用排查命令
# 查看进程
ps aux | grep jxcapp
# 查看端口
sudo lsof -i :8080
# 查看内存使用
free -h
# 查看磁盘 I/O
iostat -x 1
# 查看网络流量
iftop
# 查看最近错误
grep -i error /var/log/jxcapp/application.log | tail -20
备份与恢复
数据库备份
自动备份脚本
创建 /opt/jxcapp/backup-db.sh:
#!/bin/bash
BACKUP_DIR="/opt/jxcapp/backups"
DATE=$(date +%Y%m%d_%H%M%S)
DB_NAME="jxcapp"
DB_USER="jxcapp_user"
DB_PASS="your_secure_password"
mkdir -p $BACKUP_DIR
# 备份数据库
mysqldump -u $DB_USER -p$DB_PASS $DB_NAME | gzip > $BACKUP_DIR/db_$DATE.sql.gz
# 删除 30 天前的备份
find $BACKUP_DIR -name "db_*.sql.gz" -mtime +30 -delete
echo "Backup completed: db_$DATE.sql.gz"
设置定时任务(每天凌晨 2 点备份):
chmod +x /opt/jxcapp/backup-db.sh
crontab -e
# 添加:
0 2 * * * /opt/jxcapp/backup-db.sh >> /var/log/jxcapp/backup.log 2>&1
恢复数据库
# 解压备份文件
gunzip db_20240101_020000.sql.gz
# 恢复数据库
mysql -u jxcapp_user -p jxcapp < db_20240101_020000.sql
应用备份
# 备份 JAR 文件
cp /opt/jxcapp/jxcapp-1.0.0.jar /opt/jxcapp/backups/jxcapp-1.0.0_$(date +%Y%m%d).jar
# 备份配置文件
tar -czf /opt/jxcapp/backups/config_$(date +%Y%m%d).tar.gz \
/opt/jxcapp/.env \
/etc/systemd/system/jxcapp.service
升级与回滚
升级步骤
- 备份当前版本:
# 备份数据库
/opt/jxcapp/backup-db.sh
# 备份应用
cp /opt/jxcapp/jxcapp-1.0.0.jar /opt/jxcapp/backups/jxcapp-1.0.0_backup.jar
- 停止服务:
sudo systemctl stop jxcapp
- 部署新版本:
# 构建新版本
cd backend
mvn clean package -DskipTests
# 部署
cp target/jxcapp-1.0.0.jar /opt/jxcapp/
- 启动服务:
sudo systemctl start jxcapp
sudo systemctl status jxcapp
- 验证:
# 检查日志
tail -f /var/log/jxcapp/application.log
# 测试 API
curl http://localhost:8080/api/auth/login -X POST ...
回滚步骤
- 停止服务:
sudo systemctl stop jxcapp
- 恢复旧版本:
cp /opt/jxcapp/backups/jxcapp-1.0.0_backup.jar /opt/jxcapp/jxcapp-1.0.0.jar
- 恢复数据库(如果需要):
mysql -u jxcapp_user -p jxcapp < /opt/jxcapp/backups/db_YYYYMMDD_HHMMSS.sql
- 启动服务:
sudo systemctl start jxcapp
总结
部署检查清单
- [ ] 服务器环境准备完成(Java 21, MySQL 8.0+)
- [ ] 数据库创建并初始化
- [ ] 生产环境配置文件创建
- [ ] 环境变量配置完成
- [ ] JWT Secret 已生成并配置
- [ ] 应用构建成功
- [ ] Systemd 服务配置完成
- [ ] 防火墙规则配置
- [ ] SSL 证书配置(如需要)
- [ ] 日志目录创建
- [ ] 备份脚本配置
- [ ] 监控配置完成
- [ ] 应用启动成功
- [ ] 功能测试通过
推荐的生产环境架构
Internet
|
[Nginx/SSL]
|
+--------------+--------------+
| |
[Frontend] [Backend API]
(Static Files) (Spring Boot)
| |
+--------------+--------------+
|
[MySQL]
(Database)
联系方式与支持
如遇到问题,请:
- 查看本文档的常见问题部分
- 检查应用日志:
/var/log/jxcapp/application.log - 检查系统日志:
sudo journalctl -u jxcapp
最后更新: 2024年 文档版本: 1.0.0