文档系统
简介
  • 财贸
  • 尽消存
  • 部署指南
  • 商城
  • 建站

    • 企业/个人网站
    • 官网小程序
foo&bar
简介
  • 财贸
  • 尽消存
  • 部署指南
  • 商城
  • 建站

    • 企业/个人网站
    • 官网小程序
foo&bar
  • API文档
  • 生产环境部署详细指南

生产环境部署详细指南

📋 目录

  • 部署前准备
  • 环境要求
  • 部署方式选择
  • 方式一:单 JAR 部署(推荐)
  • 方式二:前后端分离部署
  • 数据库配置与初始化
  • 环境变量配置
  • 安全配置
  • 性能优化
  • 监控与日志
  • 常见问题与解决方案
  • 故障排查
  • 备份与恢复
  • 升级与回滚

部署前准备

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+)

软件依赖

软件版本要求说明
Java21+运行环境必需
Maven3.6+构建时必需
Node.js18+仅构建前端时必需
MySQL8.0+数据库
Nginx1.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

解决方案:

  1. 检查 Node.js 版本:
node -v  # 需要 18+
  1. 手动构建前端:
cd frontend
rm -rf node_modules package-lock.json
npm install
npm run build
  1. 跳过前端构建,手动复制:
# 构建前端
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

解决方案:

  1. 检查数据库服务:
sudo systemctl status mysql
  1. 检查网络连接:
telnet localhost 3306
# 或
nc -zv localhost 3306
  1. 检查数据库用户权限:
SHOW GRANTS FOR 'jxcapp_user'@'localhost';
  1. 检查防火墙:
sudo ufw status
  1. 增加连接超时时间: 在 application-prod.yml 中:
spring:
  datasource:
    hikari:
      connection-timeout: 60000

问题 3: 静态资源 404 错误

症状: 浏览器控制台显示 JS/CSS 文件 404

解决方案:

  1. 检查静态资源是否存在:
ls -la backend/src/main/resources/static/
  1. 确保执行了完整构建:
mvn clean package
  1. 检查 WebMvcConfig 配置: 确保 WebMvcConfig.java 中配置了静态资源映射

  2. 检查 SecurityConfig: 确保 SecurityConfig.java 中允许静态资源访问

问题 4: 前端路由 404(单页应用)

症状: 直接访问 /users 等路由返回 404

解决方案:

  1. 单 JAR 部署: 确保 WebMvcConfig.java 中配置了:
registry.addViewController("/").setViewName("forward:/index.html");
  1. 前后端分离部署: 确保 Nginx 配置了:
location / {
    try_files $uri $uri/ /index.html;
}

问题 5: CORS 跨域错误

症状:

Access to XMLHttpRequest at '...' from origin '...' has been blocked by CORS policy

解决方案:

  1. 检查 SecurityConfig 中的 CORS 配置: 确保生产环境域名已添加到允许列表

  2. 检查 Nginx 配置: 如果使用 Nginx,确保代理配置正确

  3. 临时测试(仅开发环境):

configuration.setAllowedOrigins(Arrays.asList("*"));  // 仅用于测试

问题 6: JWT Token 无效

症状: API 请求返回 401 Unauthorized

解决方案:

  1. 检查 JWT Secret: 确保生产环境使用了正确的 JWT Secret

  2. 检查 Token 过期时间:

jwt:
  expiration: 86400000  # 24 小时
  1. 检查前端 Token 存储: 确保 Token 正确存储在 localStorage 或 cookie 中

  2. 查看后端日志:

grep "JWT" /var/log/jxcapp/application.log

问题 7: 内存溢出 (OutOfMemoryError)

症状:

java.lang.OutOfMemoryError: Java heap space

解决方案:

  1. 增加堆内存:
JVM_OPTS="-Xms2g -Xmx4g"
  1. 启用堆转储:
JVM_OPTS="$JVM_OPTS -XX:+HeapDumpOnOutOfMemoryError"
JVM_OPTS="$JVM_OPTS -XX:HeapDumpPath=/var/log/jxcapp/heapdump.hprof"
  1. 分析堆转储: 使用 Eclipse MAT 或 VisualVM 分析内存泄漏

  2. 检查数据库连接泄漏:

spring:
  datasource:
    hikari:
      leak-detection-threshold: 60000

问题 8: 端口被占用

症状:

Port 8080 is already in use

解决方案:

  1. 查找占用端口的进程:
# Linux
sudo lsof -i :8080
# 或
sudo netstat -tulpn | grep 8080

# Windows
netstat -ano | findstr :8080
  1. 停止占用进程:
sudo kill -9 <PID>
  1. 更改应用端口:
server:
  port: 8081

问题 9: 数据库表不存在

症状:

Table 'jxcapp.xxx' doesn't exist

解决方案:

  1. 执行初始化脚本:
mysql -u jxcapp_user -p jxcapp < backend/src/main/resources/db/init.sql
  1. 检查 Hibernate 配置:
spring:
  jpa:
    hibernate:
      ddl-auto: validate  # 生产环境使用 validate
  1. 手动创建表: 检查 init.sql 脚本是否完整

问题 10: 启动缓慢

症状: 应用启动时间超过 1 分钟

解决方案:

  1. 检查数据库连接: 确保数据库服务器响应快速

  2. 优化 JVM 启动参数:

JVM_OPTS="$JVM_OPTS -XX:+TieredCompilation"
JVM_OPTS="$JVM_OPTS -XX:TieredStopAtLevel=1"
  1. 禁用不必要的自动配置:
@SpringBootApplication(exclude = {
    // 排除不需要的自动配置
})

故障排查

排查步骤

  1. 检查服务状态:
sudo systemctl status jxcapp
  1. 查看日志:
# 应用日志
tail -f /var/log/jxcapp/application.log

# 系统日志
sudo journalctl -u jxcapp -f

# Nginx 日志(如果使用)
tail -f /var/log/nginx/jxcapp-error.log
  1. 检查资源使用:
# CPU 和内存
top
htop

# 磁盘空间
df -h

# 网络连接
netstat -tulpn
  1. 测试数据库连接:
mysql -u jxcapp_user -p -h localhost jxcapp -e "SELECT 1;"
  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

升级与回滚

升级步骤

  1. 备份当前版本:
# 备份数据库
/opt/jxcapp/backup-db.sh

# 备份应用
cp /opt/jxcapp/jxcapp-1.0.0.jar /opt/jxcapp/backups/jxcapp-1.0.0_backup.jar
  1. 停止服务:
sudo systemctl stop jxcapp
  1. 部署新版本:
# 构建新版本
cd backend
mvn clean package -DskipTests

# 部署
cp target/jxcapp-1.0.0.jar /opt/jxcapp/
  1. 启动服务:
sudo systemctl start jxcapp
sudo systemctl status jxcapp
  1. 验证:
# 检查日志
tail -f /var/log/jxcapp/application.log

# 测试 API
curl http://localhost:8080/api/auth/login -X POST ...

回滚步骤

  1. 停止服务:
sudo systemctl stop jxcapp
  1. 恢复旧版本:
cp /opt/jxcapp/backups/jxcapp-1.0.0_backup.jar /opt/jxcapp/jxcapp-1.0.0.jar
  1. 恢复数据库(如果需要):
mysql -u jxcapp_user -p jxcapp < /opt/jxcapp/backups/db_YYYYMMDD_HHMMSS.sql
  1. 启动服务:
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)

联系方式与支持

如遇到问题,请:

  1. 查看本文档的常见问题部分
  2. 检查应用日志:/var/log/jxcapp/application.log
  3. 检查系统日志:sudo journalctl -u jxcapp

最后更新: 2024年 文档版本: 1.0.0

Prev
API文档