xinli/修复504超时错误说明.md

183 lines
6.3 KiB
Markdown
Raw Normal View History

2025-12-02 15:12:55 +08:00
# 用户导入504超时错误修复说明
## 问题描述
在导入用户档案数据时,出现 **504 Gateway Time-out** 错误。这是因为:
1. 数据量较大导入处理时间超过了网关Nginx的超时限制
2. 同步处理导致HTTP请求长时间等待响应
## 修复方案
采用**异步导入**方式将耗时的导入操作放到后台线程执行HTTP请求立即返回通过进度轮询查看导入状态。
## 修改内容
### 1. Controller层修改 ✅
**文件**: `ry-xinli-admin/src/main/java/com/ddnai/web/controller/psychology/PsyUserProfileController.java`
**修改内容**:
- 修改 `importData` 方法,调用异步导入方法 `importProfileAsync`
- 立即返回响应,告知前端导入任务已启动
- 前端通过 `/importProgress` 接口轮询获取进度
```java
@PostMapping("/importData")
public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception
{
ExcelUtil<PsyUserProfile> util = new ExcelUtil<PsyUserProfile>(PsyUserProfile.class);
List<PsyUserProfile> profileList = util.importExcel(file.getInputStream());
String operName = getUsername();
// 异步执行导入任务,立即返回
profileService.importProfileAsync(profileList, updateSupport, operName);
// 立即返回响应,告知前端导入任务已启动
return success("导入任务已启动,共 " + profileList.size() + " 条数据。请稍候查看导入进度...");
}
```
### 2. Service接口层修改 ✅
**文件**: `ry-xinli-system/src/main/java/com/ddnai/system/service/psychology/IPsyUserProfileService.java`
**修改内容**:
- 添加异步导入方法接口 `importProfileAsync`
```java
/**
* 异步导入用户档案数据(避免超时)
*/
public void importProfileAsync(List<PsyUserProfile> profileList, Boolean isUpdateSupport, String operName);
```
### 3. Service实现层修改 ✅
**文件**: `ry-xinli-system/src/main/java/com/ddnai/system/service/impl/psychology/PsyUserProfileServiceImpl.java`
**修改内容**:
- 添加 `@Async` 注解导入
- 实现异步导入方法,使用 `@Async` 注解标记
```java
import org.springframework.scheduling.annotation.Async;
@Override
@Async
public void importProfileAsync(List<PsyUserProfile> profileList, Boolean isUpdateSupport, String operName)
{
try
{
log.info("异步导入任务开始,操作人:{},数据量:{}", operName, profileList.size());
// 调用同步导入方法执行实际导入逻辑
importProfile(profileList, isUpdateSupport, operName);
log.info("异步导入任务完成,操作人:{}", operName);
}
catch (Exception e)
{
log.error("异步导入任务失败,操作人:{},错误:{}", operName, e.getMessage(), e);
}
}
```
### 4. 启动类修改 ✅
**文件**: `ry-xinli-admin/src/main/java/com/ddnai/XinliApplication.java`
**修改内容**:
- 添加 `@EnableAsync` 注解启用异步支持
- 配置异步任务线程池
```java
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
@EnableAsync
public class XinliApplication
{
@Bean(name = "taskExecutor")
public Executor taskExecutor()
{
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5); // 核心线程数
executor.setMaxPoolSize(10); // 最大线程数
executor.setQueueCapacity(100); // 队列容量
executor.setThreadNamePrefix("async-import-");
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setAwaitTerminationSeconds(60);
executor.initialize();
return executor;
}
}
```
### 5. 配置文件修改 ✅
**文件**: `ry-xinli-admin/src/main/resources/application.yml`
**修改内容**:
- 增加MVC异步请求超时配置作为保险
```yaml
spring:
mvc:
async:
# 异步请求超时时间毫秒设置为10分钟
request-timeout: 600000
```
## 工作原理
1. **文件上传**: 用户上传Excel文件
2. **解析数据**: Controller解析Excel文件为对象列表
3. **启动异步任务**: 调用 `importProfileAsync` 方法Spring会在独立线程中执行
4. **立即返回**: HTTP请求立即返回成功响应
5. **进度管理**: 后台线程执行导入,通过 `ImportProgressManager` 记录进度
6. **前端轮询**: 前端通过 `/importProgress` 接口定期查询导入进度
7. **完成通知**: 导入完成后,前端获取到最终结果并显示
## 优势
**避免超时**: HTTP请求立即返回不会因导入时间长而超时
**用户体验好**: 前端实时显示导入进度
**不阻塞服务器**: 导入任务在独立线程池中执行
**支持大批量**: 可以处理大量数据而不影响其他请求
**向后兼容**: 保留了同步导入方法,不影响其他功能
## 注意事项
⚠️ **重启应用**: 修改完成后需要重启Spring Boot应用才能生效
⚠️ **数据库连接**: 异步线程需要数据库连接,确保连接池配置足够
⚠️ **事务管理**: 异步方法中的事务与主线程独立,需注意事务边界
⚠️ **线程池监控**: 生产环境建议监控线程池状态,避免资源耗尽
## 如何测试
1. 重启Spring Boot应用
2. 准备一个包含较多数据的Excel文件建议500+条)
3. 在用户档案管理页面点击"导入"
4. 上传文件后,应该立即收到"导入任务已启动"的提示
5. 观察进度条实时更新
6. 等待导入完成,查看结果统计
## 进一步优化建议(可选)
如果仍然遇到问题,可以考虑:
1. **增加Nginx超时配置** (如果使用了Nginx反向代理):
```nginx
proxy_connect_timeout 600s;
proxy_send_timeout 600s;
proxy_read_timeout 600s;
```
2. **优化批量插入性能**:
- 已实现分批处理每批500条
- 可以根据实际情况调整批次大小
3. **数据库优化**:
- 确保相关字段有索引
- 检查批量插入SQL性能
---
**修复完成日期**: 2025-12-01
**修复人员**: Cascade AI
**影响范围**: 用户档案导入功能
**风险评估**: 低(仅改变执行方式,核心逻辑未变)