JHipster反应式网关下非反应式微服务SSE批量接收问题求助
解决反应式Gateway下非反应式微服务SSE消息批量推送问题
问题根源
反应式网关(如Spring Cloud Gateway)默认会对响应内容进行缓冲,只有当缓冲区填满或响应完成时才会将内容发送给前端。这就导致非反应式微服务中逐条发送的SSE消息被网关暂存,最终一次性推送给前端,而非预期的定时逐条推送。
解决方案
1. 关闭Gateway的响应缓冲
针对SSE路由配置禁用响应缓冲,确保网关实时转发SSE消息:
- 在Gateway的
application.yml中添加路由元数据禁用响应超时,并确保分块传输:
spring: cloud: gateway: routes: - id: news-service uri: lb://news-service predicates: - Path=/services/news/api/** filters: - RewritePath=/services/news/api/(?<segment>.*), /api/${segment} metadata: response-timeout: 0 # 禁用响应超时,维持SSE长连接
- 或者添加自定义过滤器强制开启分块传输:
@Component public class SseBufferingDisableFilter implements GatewayFilter { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { HttpHeaders headers = exchange.getResponse().getHeaders(); headers.set(HttpHeaders.TRANSFER_ENCODING, "chunked"); headers.remove(HttpHeaders.CONTENT_LENGTH); return chain.filter(exchange); } }
2. 调整后端微服务的容器配置
确保非反应式微服务的容器(如Tomcat)不会缓冲SSE响应:
在微服务的application.yml中添加:
server: tomcat: max-swallow-size: -1 # 禁用响应内容吞入,避免SSE消息被截断 connection-timeout: 0 # 关闭连接超时,保持SSE长连接 servlet: encoding: force: true
3. 验证延迟方法的正确性
确认randomDelay()方法确实实现了定时休眠,例如:
private void randomDelay() throws InterruptedException { Thread.sleep(1000); // 每次发送前等待1秒,可根据需求调整为随机延迟 }
如果该方法未正确休眠,会导致消息被快速发送,进而被网关缓冲。
4. 前端事件监听匹配后端事件名称
后端发送的SSE事件指定了name("update"),前端需对应监听该事件,而非默认的onmessage,同时修正URL参数拼接错误:
sse = new EventSource( `${serverURL}/services/news/api/words?access_token=` + (localStorage.getItem('jhi-authenticationToken') || sessionStorage.getItem('jhi-authenticationToken')) ); // 监听后端指定的"update"事件 sse.addEventListener('update', (event) => { console.log('event', event); const data = event.data; });
内容的提问来源于stack exchange,提问作者ZiebaTomasz
相关产品推荐
相关产品推荐

