sse限流需前后端协同:前端应避免主动重试、解析retry-after头、降级展示并友好提示用户;后端须在http入口层限流,返回标准429/503及retry-after,bff需透传限流响应。

SSE 本身不提供限流与流控能力,服务端拒绝是 HTTP 层行为,前端需配合响应策略而非“处理”限流。
SSE 连接被服务端限流拒绝的典型表现
- EventSource 实例触发
onerror,但eventSource.readyState === 0(连接未建立) - Network 面板中看到状态码为
429 Too Many Requests或503 Service Unavailable - 控制台无
onopen日志,反复重试后失败(默认重连间隔 3s,最多约 3 次后暂停) - 后端日志显示请求被网关(如 Nginx、API 网关)或业务层拦截,非 SSE 协议错误
前端应做的合理响应动作
- 不主动重试:避免加重服务端压力,尤其在 429 场景下应退避
- 解析响应体获取限流信息(如
Retry-After头、JSON 提示中的retry_after_ms字段) - 降级展示:切换为静态提示或轮询兜底(如“服务繁忙,请稍后再试”)
- 用户友好反馈:禁用相关操作入口,避免重复触发连接
关键代码示例(带退避逻辑)
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
let retryCount = 0;
const maxRetries = 3;
const baseDelay = 1000;
function createSSEWithBackoff(url) {
const es = new EventSource(url);
es.onerror = () => {
if (es.readyState === 0) {
// 连接失败,可能是 429/503
retryCount++;
if (retryCount createSSEWithBackoff(url), delay);
} else {
console.error('SSE 连接已达到最大重试次数');
showServiceUnavailableUI();
}
}
};
es.onopen = () => {
retryCount = 0; // 成功则重置计数
};
return es;
}
避免无效操作的注意事项
- 不要在
onerror中直接调用es.close()+new EventSource()—— 这会绕过浏览器内置重连机制,且易造成连接风暴 - 不依赖
eventSource.readyState判断是否“可用”,它只反映连接状态,不反映业务可用性 - 若服务端返回
Retry-After: 60,应在onerror中读取该响应头(需服务端开启 CORS 允许Retry-After暴露)并据此调整退避时间
真正需要协同解决的环节在服务端
- 限流策略应作用于 HTTP 请求入口(如网关层),而非 SSE 流建立后才拦截
- 建议服务端对 SSE 路径启用独立限流规则(如按 IP/Token 限制并发连接数),并返回标准
429+Retry-After - BFF 层转发 SSE 时,需同步传递上游限流响应,不能静默吞掉或转为
500
本质上,前端对限流的应对是防御性协作,不是控制手段。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










