Files
hzdyjs/docs/技术问题解决记录/SSE关闭接口406错误解决方案.md
2025-08-31 19:38:31 +08:00

252 lines
6.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SSE关闭接口406错误解决方案
## 🚨 问题描述
用户在前台退出时,SSE关闭接口返回406 Not Acceptable错误:
```
Request URL: http://hzdyjsweb.camasort.com/prod-api/resource/sse/close
Request Method: GET
Status Code: 406 Not Acceptable
```
## 🔍 问题分析
### 1. 错误原因分析
**406 Not Acceptable错误**通常表示:
- 服务器无法根据请求的内容特性完成请求
- 请求的资源的内容特性无法满足请求头中的条件
- 用户认证信息缺失或无效
### 2. 根本原因
1. **认证时机问题**:
- 前端在logout时先调用SSE关闭接口,再调用logout接口
- 此时token可能已经失效或即将失效
- 后端`LoginHelper.getUserId()`可能返回null
2. **后端接口设计问题**:
- SSE关闭接口使用了`@SaIgnore`注解,但仍然需要获取用户信息
- 缺少对空值和异常的处理
- 没有优雅降级机制
3. **nginx代理配置问题**:
- SSE关闭接口可能没有正确的代理配置
- 缺少专门的错误处理
## 🛠️ 解决方案
### 方案一:修复后端SSE关闭接口(已实施)
#### 1. 优化错误处理
```java
/**
* 关闭 SSE 连接
*/
@SaIgnore
@GetMapping(value = "${sse.path}/close")
public R<Void> close() {
try {
// 尝试获取token和用户ID,如果获取失败则直接返回成功
String tokenValue = null;
Long userId = null;
try {
tokenValue = StpUtil.getTokenValue();
userId = LoginHelper.getUserId();
} catch (Exception e) {
// 如果获取用户信息失败,记录日志但不抛出异常
log.warn("Failed to get user info for SSE close: {}", e.getMessage());
return R.ok();
}
// 如果token或userId为空,直接返回成功
if (tokenValue == null || userId == null) {
log.info("Token or userId is null, skipping SSE disconnect");
return R.ok();
}
sseEmitterManager.disconnect(userId, tokenValue);
return R.ok();
} catch (Exception e) {
log.error("Error during SSE close: {}", e.getMessage(), e);
// 即使出错也返回成功,避免影响用户退出流程
return R.ok();
}
}
```
#### 2. 关键改进点
- **添加异常捕获**:捕获所有可能的异常
- **空值检查**:检查token和userId是否为空
- **优雅降级**:即使出错也返回成功状态
- **日志记录**:记录详细的错误信息用于调试
### 方案二:优化前端logout逻辑(已实施)
#### 1. 添加错误处理
```typescript
/**
* 注销
*/
export function logout() {
// 先尝试关闭SSE连接,但不阻塞logout流程
if (import.meta.env.VITE_APP_SSE === 'true') {
request({
url: '/resource/sse/close',
method: 'get'
}).catch((error) => {
// SSE关闭失败不影响用户退出,只记录日志
console.warn('SSE close failed during logout:', error);
});
}
// 执行正常的logout流程
return request({
url: '/auth/logout',
method: 'post'
});
}
```
#### 2. 关键改进点
- **非阻塞调用**:SSE关闭失败不影响logout流程
- **错误捕获**:捕获SSE关闭接口的错误
- **日志记录**:记录错误信息但不影响用户体验
### 方案三:更新nginx配置(已实施)
#### 1. 添加SSE关闭接口专用配置
```nginx
# SSE关闭接口专用配置
location ^~ /prod-api/resource/sse/close {
proxy_pass http://47.121.125.41:8080/resource/sse/close;
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;
# 普通API配置(不需要SSE特殊配置)
proxy_connect_timeout 30s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
# CORS处理
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization,clientid';
add_header Access-Control-Allow-Credentials true;
if ($request_method = 'OPTIONS') {
return 204;
}
}
```
#### 2. 配置说明
- **独立配置**:为SSE关闭接口提供独立的代理配置
- **合理超时**:设置30秒超时,适合普通API调用
- **CORS支持**:确保跨域请求正常工作
## 📋 部署步骤
### 1. 更新后端代码
```bash
# 重新编译后端项目
mvn clean compile
# 重启后端服务
systemctl restart your-backend-service
```
### 2. 更新前端代码
```bash
# 重新构建前端项目
npm run build
# 部署到nginx目录
cp -r dist/* /root/hzdyjsweb9091/dist/
```
### 3. 更新nginx配置
```bash
# 测试nginx配置
nginx -t
# 重新加载配置
nginx -s reload
```
## 🔧 验证方法
### 1. 功能验证
1. **正常登录**:确保用户能够正常登录
2. **SSE连接**:检查SSE连接是否正常建立
3. **正常退出**:测试用户退出流程
4. **错误处理**:检查控制台是否有错误信息
### 2. 错误场景测试
1. **Token失效退出**:在token即将失效时退出
2. **网络异常退出**:在网络不稳定的情况下退出
3. **并发退出**:多个用户同时退出
### 3. 日志检查
```bash
# 检查后端日志
tail -f /path/to/backend/logs/application.log | grep -i "sse"
# 检查nginx错误日志
tail -f /var/log/nginx/hzdyjsweb.camasort.com.error.log
```
## 🎯 预期效果
### 1. 问题解决
- ✅ 消除406错误
- ✅ 用户退出流程顺畅
- ✅ 不影响用户体验
### 2. 系统稳定性
- ✅ SSE连接正确关闭
- ✅ 资源正确释放
- ✅ 错误处理完善
### 3. 监控指标
- SSE关闭成功率:100%
- 用户退出成功率:100%
- 错误日志减少:显著减少
## 📚 相关文档
- [SSE生产环境配置问题解决方案](../SSE生产环境配置问题解决方案.md)
- [nginx配置文档](../../部署文档/nginx配置/)
- [前端环境变量配置建议](../../部署文档/nginx配置/前端环境变量配置建议.md)
## 🔄 后续优化
1. **监控告警**:添加SSE关闭失败监控
2. **性能优化**:优化SSE连接管理
3. **用户体验**:添加退出进度提示
4. **错误恢复**:实现自动重试机制
---
**更新时间**:2025-01-03
**维护人员**:系统管理员
**文档版本**:v1.0