附录E:常见问题 FAQ
附录E:常见问题 FAQ
概述
本附录收集了 Spring Boot 4 升级和使用过程中的常见问题及解决方案。
E.1 升级相关
Q1: 必须升级到 Java 21 吗?
A: 是的,Spring Boot 4 要求最低 Java 21。
原因:
- 虚拟线程是 Java 21 的核心特性
- Record 模式匹配需要 Java 21
- 性能优化依赖 Java 21 的改进
迁移建议:
# 安装 JDK 21
sdk install java 21-tem
# 验证版本
java -version
Q2: 升级后应用无法启动?
A: 检查以下几点:
- JDK 版本:
java -version # 确保是 21+
- Maven/Gradle 版本:
mvn -version # 确保 3.9+
gradle -version # 确保 8.5+
- 依赖冲突:
./mvnw dependency:tree | grep -i spring
Q3: 第三方库不兼容怎么办?
A: 三种解决方案:
- 升级库版本:
<dependency>
<groupId>com.example</groupId>
<artifactId>library</artifactId>
<version>新版本</version>
</dependency>
- 排除冲突依赖:
<exclusions>
<exclusion>
<groupId>old-group</groupId>
<artifactId>old-artifact</artifactId>
</exclusion>
</exclusions>
- 暂时降级 Spring Boot(不推荐)
E.2 虚拟线程问题
Q4: 如何验证虚拟线程已启用?
A: 多种验证方法:
方法1: 代码检查:
@RestController
public class TestController {
@GetMapping("/thread-info")
public Map<String, Object> threadInfo() {
Thread thread = Thread.currentThread();
return Map.of(
"isVirtual", thread.isVirtual(),
"threadName", thread.getName()
);
}
}
方法2: 日志检查:
# 启动日志中查找
Tomcat initialized with virtual threads
方法3: Actuator:
curl http://localhost:8080/actuator/metrics/jvm.threads.virtual
Q5: 虚拟线程性能没有提升?
A: 检查以下几点:
- 应用类型: CPU 密集型应用收益不明显
- synchronized 使用: 导致线程固定
- 连接池配置: 可能成为瓶颈
诊断:
# 启用 pinning 检测
java -Djdk.tracePinnedThreads=full -jar app.jar
Q6: 虚拟线程数量过多导致内存问题?
A: 虚拟线程本身占用很少(~1KB),但要注意:
- ThreadLocal 清理:
// 使用后清理
threadLocal.remove();
- 限制并发数:
Semaphore semaphore = new Semaphore(10000);
semaphore.acquire();
try {
// 处理
} finally {
semaphore.release();
}
E.3 性能问题
Q7: 启动时间没有明显改善?
A: 尝试以下优化:
- 启用 AOT:
spring:
aot:
enabled: true
- 使用 Native Image:
./mvnw -Pnative native:compile
- 优化依赖:
<!-- 移除不必要的 starter -->
Q8: 运行时性能反而下降?
A: 可能的原因:
- 未启用虚拟线程:
spring:
threads:
virtual:
enabled: true # 确保启用
- 连接池配置不当:
spring:
datasource:
hikari:
maximum-pool-size: 20 # 减小连接池
- synchronized 过多: 使用 Lock 替代
E.4 数据库问题
Q9: 数据库连接池耗尽?
A: 虚拟线程下需要调整配置:
spring:
datasource:
hikari:
maximum-pool-size: 20 # 从 50 减少到 20
minimum-idle: 5
connection-timeout: 30000
原因: 虚拟线程可以用更少的连接处理更多请求
Q10: 事务超时?
A: 检查事务配置:
@Transactional(timeout = 30) // 增加超时时间
public void longRunningTransaction() {
// ...
}
E.5 安全问题
Q11: Security 配置报错?
A: 使用新的 Lambda DSL:
错误代码:
http.authorizeRequests()
.antMatchers("/public/**").permitAll()
.and()... // ❌ .and() 已废弃
正确代码:
http.authorizeHttpRequests(auth -> auth
.requestMatchers("/public/**").permitAll()
.anyRequest().authenticated()
);
Q12: JWT 验证失败?
A: 检查密钥配置:
app:
jwt:
secret: ${JWT_SECRET} # 确保环境变量设置
expiration: 86400000
E.6 部署问题
Q13: Docker 镜像过大?
A: 使用多阶段构建:
FROM eclipse-temurin:21-jdk AS builder
WORKDIR /app
COPY . .
RUN ./mvnw clean package -DskipTests
FROM eclipse-temurin:21-jre
COPY --from=builder /app/target/*.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]
或使用 Native Image:
./mvnw -Pnative native:compile
# 镜像大小: 250MB → 60MB
Q14: Kubernetes 健康检查失败?
A: 配置正确的探针:
management:
endpoint:
health:
probes:
enabled: true
Kubernetes:
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 30
E.7 监控问题
Q15: Prometheus 指标缺失?
A: 确保配置正确:
management:
endpoints:
web:
exposure:
include: prometheus
prometheus:
metrics:
export:
enabled: true
Q16: 追踪信息不显示?
A: 启用追踪:
management:
tracing:
enabled: true
sampling:
probability: 1.0
E.8 迁移问题
Q17: 迁移需要多长时间?
A: 根据项目规模:
| 项目规模 | 预估时间 | 说明 |
|---|---|---|
| 小型 (< 10K 行) | 1-2 周 | 主要是测试 |
| 中型 (10K-50K 行) | 3-4 周 | 需要仔细测试 |
| 大型 (> 50K 行) | 6-8 周 | 分模块迁移 |
Q18: 可以部分迁移吗?
A: 可以,建议策略:
- 先迁移独立模块
- 逐步迁移核心服务
- 最后迁移遗留系统
E.9 最佳实践
Q19: 什么时候应该升级?
A: 推荐场景:
✅ 立即升级:
- I/O 密集型应用
- 高并发服务
- 微服务架构
⚠️ 谨慎评估:
- CPU 密集型应用
- 大量使用废弃 API
- 第三方库依赖多
❌ 暂缓升级:
- 稳定运行的遗留系统
- 团队不熟悉 Java 21
- 第三方库不兼容
Q20: 如何最大化性能收益?
A: 关键点:
- 启用虚拟线程
- 优化连接池
- 使用 Native Image
- 监控和调优
预期收益:
- 吞吐量: 2-5 倍
- 延迟: 50-80% 降低
- 内存: 30-50% 节省
E.10 获取帮助
官方资源
社区支持
最后更新: 2024-12-24
版本: Spring Boot 4.0.0
相关章节: