Vaadin 24.x升级后Broadcaster重复日志报错及UI卡顿求助
Vaadin 24.x + Tomcat 10.1.8 Push功能报错导致UI卡顿问题解决
问题背景
将Vaadin应用从23.x版本升级至24.x,同时切换运行环境为Tomcat 10.1.8,当前使用@Push(PushMode.AUTOMATIC),Servlet配置如下:
@WebServlet(urlPatterns = "/*", name = "MyApp", asyncSupported = true, initParams = { @WebInitParam(name = "productionMode", value = "true"), @WebInitParam(name = "heartbeatInterval", value = "30"), @WebInitParam(name = "closeIdleSessions", value = "false")})
系统反复输出以下WARN日志,且UI运行卡顿:
[Atmosphere-Shared-0] WARN org.atmosphere.cpr.DefaultBroadcaster - This message Entry{message=com.vaadin.flow.server.communication.AtmospherePushConnection$PushMessage@65df019a, type=RESOURCE, future=org.atmosphere.cpr.BroadcasterFuture@4dfa5742} will be lost [Atmosphere-Shared-0] WARN org.atmosphere.cpr.DefaultBroadcaster - Failed to submit broadcast handler runnable to for Broadcaster/* java.lang.IllegalStateException: The request object has been recycled and is no longer associated with this facade at org.apache.catalina.connector.RequestFacade.checkFacade(RequestFacade.java:856) at org.apache.catalina.connector.RequestFacade.getHeader(RequestFacade.java:505) at jakarta.servlet.http.HttpServletRequestWrapper.getHeader(HttpServletRequestWrapper.java:82) at org.atmosphere.cpr.AtmosphereRequestImpl.getHeader(AtmosphereRequestImpl.java:351) at org.atmosphere.cpr.AtmosphereRequestImpl.getHeader(AtmosphereRequestImpl.java:336) at com.vaadin.flow.server.communication.LongPollingCacheFilter.filter(LongPollingCacheFilter.java:56) at org.atmosphere.cpr.BroadcasterConfig.filter(BroadcasterConfig.java:452) at org.atmosphere.cpr.DefaultBroadcaster.perRequestFilter(DefaultBroadcaster.java:818) at org.atmosphere.cpr.DefaultBroadcaster.deliverPush(DefaultBroadcaster.java:691) at org.atmosphere.cpr.DefaultBroadcaster.push(DefaultBroadcaster.java:568) at org.atmosphere.cpr.DefaultBroadcaster$1.run(DefaultBroadcaster.java:423) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1395) at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373) at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182) at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655) at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622) at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165)
未找到该报错的相关参考资料,仅看到Spring相关配置案例,但应用并未使用Spring。
问题原因与解决办法
这个问题属于Vaadin 24.x与Tomcat 10+环境下的兼容问题,核心是Tomcat对请求对象的回收机制与Atmosphere的Long Polling处理逻辑冲突,导致广播消息时访问已被回收的请求对象。可通过以下配置调整解决:
1. 切换Push传输模式
将默认的Long Polling模式替换为WebSocket,这是最直接的解决方案。修改@Push注解:
@Push(value = PushMode.AUTOMATIC, transport = Transport.WEBSOCKET)
若WebSocket不可用,可指定WebSocket降级为XHR的方案:
@Push(value = PushMode.AUTOMATIC, transport = Transport.WEBSOCKET_XHR)
2. 调整Servlet初始化参数
添加Atmosphere线程池配置,禁用共享线程池,避免请求对象被回收后仍被访问:
@WebServlet(urlPatterns = "/*", name = "MyApp", asyncSupported = true, initParams = { @WebInitParam(name = "productionMode", value = "true"), @WebInitParam(name = "heartbeatInterval", value = "30"), @WebInitParam(name = "closeIdleSessions", value = "false"), @WebInitParam(name = "org.atmosphere.cpr.broadcaster.shareableThreadPool", value = "false") })
3. 验证Tomcat WebSocket支持
确保Tomcat 10.1.8的conf/web.xml中启用了WebSocket支持(默认已启用),检查是否存在以下Servlet配置:
<servlet> <servlet-name>jakarta.websocket.server.ServerContainer</servlet-name> <servlet-class>jakarta.websocket.server.ServerContainer</servlet-class> </servlet>
4. 升级Vaadin补丁版本
如果以上配置调整后问题仍存在,建议升级至Vaadin 24.x的最新补丁版本,官方后续更新已修复部分Atmosphere与Tomcat 10的兼容问题。
内容的提问来源于stack exchange,提问作者andhalib
相关产品推荐
相关产品推荐

