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

6.4 KiB
Raw Blame History

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. 优化错误处理

/**
 * 关闭 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. 添加错误处理

/**
 * 注销
 */
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关闭接口专用配置

# 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. 更新后端代码

# 重新编译后端项目
mvn clean compile

# 重启后端服务
systemctl restart your-backend-service

2. 更新前端代码

# 重新构建前端项目
npm run build

# 部署到nginx目录
cp -r dist/* /root/hzdyjsweb9091/dist/

3. 更新nginx配置

# 测试nginx配置
nginx -t

# 重新加载配置
nginx -s reload

🔧 验证方法

1. 功能验证

  1. 正常登录:确保用户能够正常登录
  2. SSE连接:检查SSE连接是否正常建立
  3. 正常退出:测试用户退出流程
  4. 错误处理:检查控制台是否有错误信息

2. 错误场景测试

  1. Token失效退出:在token即将失效时退出
  2. 网络异常退出:在网络不稳定的情况下退出
  3. 并发退出:多个用户同时退出

3. 日志检查

# 检查后端日志
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%
  • 错误日志减少:显著减少

📚 相关文档

🔄 后续优化

  1. 监控告警:添加SSE关闭失败监控
  2. 性能优化:优化SSE连接管理
  3. 用户体验:添加退出进度提示
  4. 错误恢复:实现自动重试机制

更新时间:2025-01-03
维护人员:系统管理员
文档版本:v1.0