奶糖 肥晨头像
关注

mac系统中Java项目环境配置与问题解决全记录|项目启动篇:从编译打包到生产级部署

在这里插入图片描述

文章目录


Spring Boot 项目启动与运维完全指南

—— 从编译打包到生产级部署的全流程详解


📖 写在前面

在前两篇文章中,我们完成了:

  • 第一篇:JDK 17 + Maven 3.9.8 的环境配置
  • 第二篇:MySQL 8.0 + Redis 的安装与数据初始化

现在,所有准备工作已经就绪,是时候启动 Spring Boot 应用了。然而,java -jar 只是万里长征的第一步。应用启动过程中可能遇到各种问题:端口冲突、内存不足、配置文件错误、数据库连接池耗尽、日志配置不当……

本文将极其详细地讲解:

  1. Spring Boot 应用的多种启动方式与参数调优
  2. 启动失败问题的系统化排查方法论
  3. 应用健康检查与性能监控
  4. 生产级部署的最佳实践
  5. 常见运维场景的操作指南

第一章:Spring Boot 应用启动全览

1.1 项目结构回顾

~/Desktop/FeiChenERP/backend/
├── pom.xml                          # Maven项目配置
├── src/
│   ├── main/
│   │   ├── java/                    # Java源代码
│   │   │   └── com/erp/
│   │   │       ├── OpenerpApplication.java  # 启动类
│   │   │       ├── controller/      # 控制器层
│   │   │       ├── service/         # 业务逻辑层
│   │   │       ├── repository/      # 数据访问层
│   │   │       └── config/          # 配置类
│   │   ├── resources/
│   │   │   ├── application.yml      # 主配置文件
│   │   │   ├── application-dev.yml  # 开发环境配置
│   │   │   ├── application-prod.yml # 生产环境配置
│   │   │   ├── static/              # 静态资源
│   │   │   └── templates/           # 模板文件
│   │   └── webapp/                  # Web资源(可选)
│   └── test/                        # 测试代码
└── target/                          # 编译输出目录
    ├── classes/                     # 编译后的class文件
    ├── openerp-backend-1.0.0.jar   # 可执行JAR包
    └── openerp-backend-1.0.0.jar.original  # 原始JAR(不含依赖)

1.2 Spring Boot 启动原理简述

Spring Boot 应用启动的核心流程:

java -jar app.jar
         ↓
    加载 META-INF/MANIFEST.MF
         ↓
    定位 Main-Class: org.springframework.boot.loader.JarLauncher
         ↓
    JarLauncher 启动嵌入式 Tomcat
         ↓
    加载 Spring 容器配置
         ↓
    执行 AutoConfiguration(自动配置)
         ↓
    初始化 DataSource、Redis、JPA 等组件
         ↓
    执行 CommandLineRunner / ApplicationRunner
         ↓
    应用启动完成,监听端口(默认 8080)

1.3 可执行 JAR 包结构

Spring Boot 生成的 JAR 包是一个 “Fat JAR”(胖JAR),包含了所有依赖:

# 查看JAR包内容
jar tf target/openerp-backend-1.0.0.jar | head -30

# 输出结构:
# META-INF/
# META-INF/MANIFEST.MF          # 清单文件,定义启动类
# BOOT-INF/
# BOOT-INF/classes/              # 应用编译后的class文件
# BOOT-INF/lib/                  # 所有依赖JAR包(可能有几十到上百个)
# org/
# org/springframework/boot/loader/  # Spring Boot类加载器

JAR包大小分析

# 查看JAR包大小
ls -lh target/openerp-backend-1.0.0.jar

# 分析JAR包组成
unzip -l target/openerp-backend-1.0.0.jar | sort -nr -k3 | head -20
# 可以找出最大的依赖包

第二章:Spring Boot 启动方式详解

2.1 方式一:标准启动(最常用)

cd ~/Desktop/FeiChenERP/backend
java -jar target/openerp-backend-1.0.0.jar

启动日志解读

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v3.2.5)
                    ↑ Spring Boot 版本

2026-07-26 10:30:15.123  INFO 12345 --- [           main] com.erp.OpenerpApplication               : Starting OpenerpApplication v1.0.0 using Java 17.0.11 with PID 12345 (/Users/xxx/Desktop/FeiChenERP/backend/target/openerp-backend-1.0.0.jar started by xxx in /Users/xxx/Desktop/FeiChenERP/backend)
                    ↑ 启动信息:应用名、版本、Java版本、进程ID、JAR路径、工作目录

2026-07-26 10:30:15.456  INFO 12345 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
                    ↑ 嵌入式Tomcat初始化,监听8080端口

2026-07-26 10:30:15.789  INFO 12345 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2026-07-26 10:30:16.123  INFO 12345 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
                    ↑ 数据库连接池初始化

2026-07-26 10:30:16.456  INFO 12345 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path ''
                    ↑ Tomcat启动完成,上下文路径为空(即根路径)

2026-07-26 10:30:16.789  INFO 12345 --- [           main] com.erp.OpenerpApplication               : Started OpenerpApplication in 3.456 seconds (process running for 4.123)
                    ↑ 应用启动完成,耗时3.456秒

2.2 方式二:指定配置启动

# 覆盖单个配置项
java -jar target/openerp-backend-1.0.0.jar \
  --server.port=9090 \
  --spring.datasource.url="jdbc:mysql://localhost:3306/openerp?useSSL=false" \
  --spring.datasource.password=123456 \
  --spring.sql.init.mode=never

常用覆盖参数

参数默认值说明
--server.port8080HTTP服务端口
--server.context-path应用上下文路径
--spring.profiles.activedefault激活的配置文件
--spring.datasource.url配置文件中数据库连接URL
--spring.datasource.username配置文件中数据库用户名
--spring.datasource.password配置文件中数据库密码
--spring.redis.hostlocalhostRedis主机
--spring.redis.port6379Redis端口
--logging.level.rootINFO日志级别
--spring.sql.init.modeembeddedSQL初始化模式

2.3 方式三:使用配置文件启动

# 使用外部的application.yml
java -jar target/openerp-backend-1.0.0.jar \
  --spring.config.location=file:/path/to/application.yml

# 使用环境特定的配置文件
java -jar target/openerp-backend-1.0.0.jar \
  --spring.profiles.active=prod \
  --spring.config.additional-location=file:/etc/erp/config/

配置文件加载优先级(从高到低):

  1. 命令行参数
  2. 操作系统环境变量(SPRING_APPLICATION_JSON
  3. JAR包外的 application-{profile}.properties/yml
  4. JAR包内的 application-{profile}.properties/yml
  5. JAR包外的 application.properties/yml
  6. JAR包内的 application.properties/yml

2.4 方式四:后台守护启动(生产环境)

# 使用nohup
nohup java -jar target/openerp-backend-1.0.0.jar \
  --spring.profiles.active=prod \
  > logs/app.log 2>&1 &

# 记录进程ID
echo $! > app.pid

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

# 停止应用
kill $(cat app.pid)

nohup 参数说明

符号含义
nohup忽略挂断信号(终端关闭不影响进程)
> logs/app.log标准输出重定向到日志文件
2>&1标准错误重定向到标准输出(也写入日志)
&后台运行
$!最后一个后台进程的PID

2.5 方式五:使用系统服务(生产环境)

创建 Systemd 服务(Linux)
# /etc/systemd/system/openerp.service
[Unit]
Description=OpenERP Backend Application
After=network.target mysql.service redis.service

[Service]
Type=simple
User=erpuser
WorkingDirectory=/opt/openerp/backend
ExecStart=/usr/bin/java -jar /opt/openerp/backend/openerp-backend-1.0.0.jar --spring.profiles.active=prod
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
Environment="JAVA_HOME=/usr/lib/jvm/java-17"

[Install]
WantedBy=multi-user.target
# 启动服务
sudo systemctl start openerp

# 设置开机自启动
sudo systemctl enable openerp

# 查看状态
sudo systemctl status openerp

# 查看日志
sudo journalctl -u openerp -f
创建 Launch Agent(macOS)
<!-- ~/Library/LaunchAgents/com.erp.openerp.plist -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.erp.openerp</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/bin/java</string>
        <string>-jar</string>
        <string>/Users/xxx/Desktop/FeiChenERP/backend/openerp-backend-1.0.0.jar</string>
        <string>--spring.profiles.active=prod</string>
        <string>--server.port=8080</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>KeepAlive</key>
    <true/>
    <key>WorkingDirectory</key>
    <string>/Users/xxx/Desktop/FeiChenERP/backend</string>
    <key>StandardOutPath</key>
    <string>/Users/xxx/Desktop/FeiChenERP/backend/logs/app.log</string>
    <key>StandardErrorPath</key>
    <string>/Users/xxx/Desktop/FeiChenERP/backend/logs/error.log</string>
</dict>
</plist>

第三章:JVM参数调优详解

3.1 JVM内存模型

┌─────────────────────────────────────────────────────────────┐
│                        JVM 内存                              │
├─────────────────────────────────────────────────────────────┤
│  ┌─────────────────────┐  ┌─────────────────────────────┐  │
│  │     堆内存 (Heap)     │  │    非堆内存 (Non-Heap)       │  │
│  │  ┌──────┐ ┌──────┐  │  │  ┌──────────┐ ┌──────────┐  │  │
│  │  │Young │ │ Old  │  │  │  │ Metaspace│ │  Code    │  │  │
│  │  │Gen   │ │ Gen  │  │  │  │          │ │  Cache   │  │  │
│  │  └──────┘ └──────┘  │  │  └──────────┘ └──────────┘  │  │
│  └─────────────────────┘  └─────────────────────────────┘  │
│       ↑ 对象实例              ↑ 类元数据、JIT编译代码        │
│       ↑ 由GC管理              ↑ 无GC或弱GC                  │
└─────────────────────────────────────────────────────────────┘

3.2 关键JVM参数

java -Xms2g -Xmx2g -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m \
     -XX:+UseG1GC -XX:MaxGCPauseMillis=200 \
     -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/log/erp/dump.hprof \
     -jar target/openerp-backend-1.0.0.jar

参数详解

参数说明推荐值
-Xms初始堆内存大小-Xmx 相同,避免动态调整
-Xmx最大堆内存大小物理内存的60-70%(如8GB内存设4-5GB)
-Xmn年轻代大小堆大小的1/3
-XX:MetaspaceSize元空间初始大小256m
-XX:MaxMetaspaceSize元空间最大大小512m
-XX:+UseG1GC使用G1垃圾回收器Java 9+默认,适合大堆内存
-XX:MaxGCPauseMillisGC最大暂停时间目标200ms
-XX:+HeapDumpOnOutOfMemoryErrorOOM时导出堆转储建议开启
-XX:HeapDumpPath堆转储文件路径指定目录

3.3 GC日志配置

java -jar target/openerp-backend-1.0.0.jar \
  -Xlog:gc*:file=logs/gc.log:time,uptime,level,tags:filecount=5,filesize=50m \
  -XX:+PrintGCDetails \
  -XX:+PrintGCDateStamps

3.4 完整启动脚本示例

#!/bin/bash
# start.sh - 生产环境启动脚本

APP_NAME="openerp-backend"
APP_VERSION="1.0.0"
JAR_FILE="target/${APP_NAME}-${APP_VERSION}.jar"
LOG_DIR="logs"
PID_FILE="${APP_NAME}.pid"

# JVM参数
JAVA_OPTS="-Xms2g -Xmx2g -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m"
JAVA_OPTS="${JAVA_OPTS} -XX:+UseG1GC -XX:MaxGCPauseMillis=200"
JAVA_OPTS="${JAVA_OPTS} -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${LOG_DIR}/heapdump.hprof"
JAVA_OPTS="${JAVA_OPTS} -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:${LOG_DIR}/gc.log"

# Spring参数
SPRING_OPTS="--spring.profiles.active=prod"
SPRING_OPTS="${SPRING_OPTS} --spring.sql.init.mode=never"

start() {
    echo "Starting ${APP_NAME}..."
    mkdir -p ${LOG_DIR}
    nohup java ${JAVA_OPTS} -jar ${JAR_FILE} ${SPRING_OPTS} \
        > ${LOG_DIR}/app.log 2>&1 &
    echo $! > ${PID_FILE}
    echo "Started with PID $(cat ${PID_FILE})"
}

stop() {
    echo "Stopping ${APP_NAME}..."
    if [ -f ${PID_FILE} ]; then
        kill $(cat ${PID_FILE})
        rm ${PID_FILE}
        echo "Stopped"
    else
        echo "PID file not found"
    fi
}

status() {
    if [ -f ${PID_FILE} ]; then
        PID=$(cat ${PID_FILE})
        if ps -p ${PID} > /dev/null 2>&1; then
            echo "${APP_NAME} is running with PID ${PID}"
        else
            echo "${APP_NAME} is not running (stale PID file)"
        fi
    else
        echo "${APP_NAME} is not running"
    fi
}

case "$1" in
    start)   start ;;
    stop)    stop ;;
    restart) stop && sleep 2 && start ;;
    status)  status ;;
    *)       echo "Usage: $0 {start|stop|restart|status}" ;;
esac

第四章:启动失败问题系统化排查

4.1 排查方法论

启动失败
    ↓
查看日志(最快信息源)
    ↓
识别错误类型
    ↓
    ├── 数据库相关 ──→ 检查MySQL连接
    ├── Redis相关 ──→ 检查Redis连接
    ├── 端口冲突 ──→ 检查端口占用
    ├── 内存不足 ──→ 调整JVM参数
    ├── 配置错误 ──→ 检查配置文件
    ├── 类加载失败 ──→ 检查依赖冲突
    └── 其他异常 ──→ 分析具体堆栈

4.2 常见启动错误及解决方案

错误 1:端口被占用
APPLICATION FAILED TO START
***************************

Description:
Web server failed to start. Port 8080 was already in use.

Action:
Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.

解决方案

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

# 2. 结束进程
kill -9 [PID]

# 3. 或修改应用端口
java -jar app.jar --server.port=9090

# 4. 或使用系统属性
java -Dserver.port=9090 -jar app.jar
错误 2:数据库连接失败
APPLICATION FAILED TO START
***************************

Description:
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.

Reason: Failed to determine a suitable driver class

原因:Spring Boot 无法连接到配置的数据库。

解决方案

# 1. 检查MySQL是否运行
ps aux | grep mysql
mysqladmin -u root -p status

# 2. 检查配置文件
cat src/main/resources/application.yml | grep -A5 "datasource"

# 3. 手动测试数据库连接
mysql -u root -p123456 -h localhost -P 3306 -e "SELECT 1"

# 4. 检查数据库是否存在
mysql -u root -p123456 -e "SHOW DATABASES LIKE 'openerp'"

# 5. 启动时指定数据库配置
java -jar app.jar \
  --spring.datasource.url="jdbc:mysql://localhost:3306/openerp?useSSL=false&allowPublicKeyRetrieval=true" \
  --spring.datasource.username=root \
  --spring.datasource.password=123456
错误 3:Redis连接失败
Redis connection failed: Connection refused: localhost/127.0.0.1:6379

解决方案

# 1. 启动Redis
brew services start redis
# 或
redis-server --daemonize yes

# 2. 测试连接
redis-cli ping

# 3. 如果应用强制要求Redis,暂时禁用Redis配置
java -jar app.jar --spring.data.redis.repositories.enabled=false
错误 4:OutOfMemoryError
java.lang.OutOfMemoryError: Java heap space

解决方案

# 增加堆内存
java -Xmx2g -Xms2g -jar app.jar

# 增加元空间大小
java -XX:MaxMetaspaceSize=512m -jar app.jar

# 启用G1GC优化
java -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -jar app.jar
错误 5:类找不到
java.lang.ClassNotFoundException: org.springframework.boot.SpringApplication

原因:JAR包不完整或损坏。

解决方案

# 1. 重新构建
mvn clean package -DskipTests

# 2. 检查JAR包完整性
jar tf target/openerp-backend-1.0.0.jar | grep SpringApplication

# 3. 检查Maven依赖
mvn dependency:tree

# 4. 清理本地仓库(修复损坏依赖)
rm -rf ~/.m2/repository/org/springframework/boot
mvn clean package -DskipTests

4.3 日志级别调整

# 启动时调整日志级别
java -jar app.jar \
  --logging.level.root=DEBUG \
  --logging.level.org.springframework.boot=DEBUG \
  --logging.level.com.erp=DEBUG

# 在application.yml中配置
logging:
  level:
    root: INFO
    com.erp: DEBUG
    org.springframework.boot: INFO
    org.hibernate: DEBUG
    com.zaxxer.hikari: DEBUG

4.4 调试模式启动

# 远程调试(端口 5005)
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 \
  -jar app.jar

# IDEA中连接:Run → Debug → Remote JVM Debug
# Host: localhost, Port: 5005

第五章:应用健康检查与监控

5.1 Spring Boot Actuator 配置

Spring Boot Actuator 提供了生产级的监控和管理端点。

# application.yml
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,env,configprops
      base-path: /actuator
  endpoint:
    health:
      show-details: always
      show-components: always
  info:
    env:
      enabled: true

info:
  app:
    name: ${spring.application.name}
    version: @project.version@
    description: @project.description@
  build:
    artifact: @project.artifactId@
    time: @maven.build.timestamp@

5.2 健康检查端点

# 基础健康检查
curl http://localhost:8080/actuator/health

# 响应示例
{
  "status": "UP",
  "components": {
    "db": {
      "status": "UP",
      "details": {
        "database": "MySQL",
        "validationQuery": "isValid()"
      }
    },
    "redis": {
      "status": "UP",
      "details": {
        "version": "7.2.4"
      }
    },
    "diskSpace": {
      "status": "UP",
      "details": {
        "total": 500068036608,
        "free": 234567890123,
        "threshold": 10485760
      }
    }
  }
}

# 详细健康信息(需要 management.endpoint.health.show-details=always)
curl http://localhost:8080/actuator/health | jq .

5.3 自定义健康检查

@Component
public class CustomHealthIndicator implements HealthIndicator {
    
    @Override
    public Health health() {
        boolean isHealthy = checkExternalService();
        if (isHealthy) {
            return Health.up()
                .withDetail("service", "External API")
                .withDetail("status", "Available")
                .build();
        }
        return Health.down()
            .withDetail("service", "External API")
            .withDetail("status", "Unavailable")
            .withDetail("error", "Connection timeout")
            .build();
    }
}

5.4 应用信息端点

# 查看应用信息
curl http://localhost:8080/actuator/info

# 查看指标
curl http://localhost:8080/actuator/metrics

# 查看特定指标(如内存使用)
curl http://localhost:8080/actuator/metrics/jvm.memory.used

# 查看线程信息
curl http://localhost:8080/actuator/threaddump

# 查看环境属性
curl http://localhost:8080/actuator/env

第六章:日志管理详解

6.1 Logback 配置

创建 src/main/resources/logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 控制台输出 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!-- 文件输出 - 所有日志 -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>logs/openerp.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>logs/openerp.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!-- 错误日志单独输出 -->
    <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>logs/error.log</file>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>logs/error.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <!-- 异步日志(提高性能) -->
    <appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
        <appender-ref ref="FILE"/>
        <queueSize>1024</queueSize>
        <discardingThreshold>0</discardingThreshold>
    </appender>

    <!-- 根日志级别 -->
    <root level="INFO">
        <appender-ref ref="CONSOLE"/>
        <appender-ref ref="ASYNC"/>
        <appender-ref ref="ERROR_FILE"/>
    </root>

    <!-- 特定包的日志级别 -->
    <logger name="com.erp" level="DEBUG"/>
    <logger name="org.springframework.web" level="INFO"/>
    <logger name="org.hibernate" level="INFO"/>
    <logger name="com.zaxxer.hikari" level="INFO"/>
</configuration>

6.2 日志切割与归档

# application.yml 日志配置
logging:
  file:
    name: logs/openerp.log
    path: logs/
  logback:
    rollingpolicy:
      max-file-size: 100MB
      max-history: 30
      total-size-cap: 10GB
      clean-history-on-start: true

6.3 日志查看与分析

# 实时查看日志
tail -f logs/app.log

# 查看最近100行
tail -100 logs/app.log

# 搜索错误
grep ERROR logs/app.log

# 统计错误数量
grep -c ERROR logs/app.log

# 查看特定时间段的日志
sed -n '/2026-07-26 10:/,/2026-07-26 11:/p' logs/app.log

# 使用less查看大日志
less logs/app.log
# 在less中: / 搜索, G 跳到末尾, g 跳到开头

6.4 日志级别动态调整

# 通过Actuator调整日志级别(需要开启)
curl -X POST http://localhost:8080/actuator/loggers/com.erp \
  -H "Content-Type: application/json" \
  -d '{"configuredLevel": "DEBUG"}'

# 查看当前日志级别
curl http://localhost:8080/actuator/loggers/com.erp

第七章:性能优化与压测

7.1 应用性能调优

数据库连接池优化
spring:
  datasource:
    hikari:
      # 连接池大小
      maximum-pool-size: 20
      minimum-idle: 5
      # 连接超时
      connection-timeout: 30000
      idle-timeout: 600000
      max-lifetime: 1800000
      # 验证查询
      connection-test-query: SELECT 1
      validation-timeout: 3000
线程池优化
server:
  tomcat:
    threads:
      max: 200
      min-spare: 10
    max-connections: 10000
    connection-timeout: 20000
    accept-count: 100

7.2 压力测试

# 使用 Apache Bench (ab)
# 安装
brew install httpd  # macOS
sudo apt install apache2-utils  # Ubuntu

# 基础压测
ab -n 1000 -c 10 http://localhost:8080/api/health

# 参数说明
# -n: 总请求数
# -c: 并发数
# -H: 添加请求头
# -p: POST数据文件
# -T: Content-Type

# 使用 wrk (更强大)
# 安装
brew install wrk

# 压测
wrk -t 4 -c 100 -d 30s http://localhost:8080/api/users
# -t: 线程数
# -c: 连接数
# -d: 持续时间

7.3 性能监控指标

# 查看JVM内存使用
curl http://localhost:8080/actuator/metrics/jvm.memory.used

# 查看GC情况
curl http://localhost:8080/actuator/metrics/jvm.gc.pause

# 查看请求QPS
curl http://localhost:8080/actuator/metrics/http.server.requests

# 查看数据库连接池
curl http://localhost:8080/actuator/metrics/hikaricp.connections

第八章:运维场景实战

8.1 优雅关闭应用

Spring Boot 支持优雅关闭:

server:
  shutdown: graceful

spring:
  lifecycle:
    timeout-per-shutdown-phase: 30s
# 发送SIGTERM信号触发优雅关闭
kill -15 $(cat app.pid)
# 或
pkill -15 -f openerp-backend

8.2 应用版本回滚

# 保留多个版本
ls -la releases/
# openerp-backend-1.0.0.jar
# openerp-backend-1.0.1.jar
# openerp-backend-1.0.2.jar

# 创建符号链接
ln -sf releases/openerp-backend-1.0.1.jar current/openerp-backend.jar

# 重启应用
./start.sh restart

8.3 数据库迁移

# 使用Flyway或Liquibase进行版本化数据库迁移
# 或手动执行SQL脚本
mysql -u root -p123456 openerp < migrations/V1.1__add_new_table.sql

# 验证迁移结果
mysql -u root -p123456 openerp -e "SHOW TABLES;"

8.4 应用备份与恢复

# 备份JAR包
cp target/openerp-backend-1.0.0.jar backups/openerp-backend-$(date +%Y%m%d).jar

# 备份配置文件
cp src/main/resources/application.yml backups/application-$(date +%Y%m%d).yml

# 备份数据库
mysqldump -u root -p123456 openerp > backups/openerp-$(date +%Y%m%d).sql

# 恢复数据库
mysql -u root -p123456 openerp < backups/openerp-20260726.sql

8.5 快速问题诊断命令集

# 一键检查应用状态
echo "=== 应用状态 ===" && ps aux | grep openerp | grep -v grep && \
echo "=== 端口监听 ===" && lsof -i :8080 && \
echo "=== MySQL状态 ===" && mysqladmin -u root -p123456 status && \
echo "=== Redis状态 ===" && redis-cli ping && \
echo "=== 健康检查 ===" && curl -s http://localhost:8080/actuator/health | jq .status && \
echo "=== 最近错误 ===" && tail -20 logs/app.log | grep ERROR

第九章:总结与最佳实践

9.1 启动运维清单

检查项命令/方法预期结果
应用是否运行ps aux | grep app.jar看到进程
端口是否监听`lsof -

您好,我是肥晨。
欢迎关注我获取前端/AI学习资源,日常分享技术变革,生存法则;行业内幕,洞察先机。

转载自 CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/weixin_48998573/article/details/163221192

文章来源crawl

评论

赞0

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--