Vaadin 8迁移至14后生产环境Tomcat 9出现HEARTBEAT/PUSH路由NotFound及内存溢出问题求助
排查Vaadin 14生产环境HEARTBEAT/PUSH 404及OOM问题
从你描述的情况来看,核心问题是Vaadin内部的HEARTBEAT和PUSH请求没有被正确路由到Vaadin Servlet,而是被Flow的路由系统拦截返回404,大量错误日志积累最终引发OutOfMemoryError。本地环境正常但生产环境异常,大概率是生产环境的代理或Servlet配置差异导致的,以下是具体的排查方向和检查建议:
1. 优先排查Apache 2.4反向代理配置
因为旧Vaadin7应用在同一生产环境能正常处理这些请求,说明问题出在新应用的代理规则上:
- 对比旧Vaadin7的Apache配置,检查是否遗漏了针对Vaadin 14特殊端点的转发规则。Vaadin 14的核心端点包括
/HEARTBEAT、/PUSH、/UIDL、/vaadinServlet/*等,需要确保这些路径都正确转发到Tomcat实例。 - 检查Apache的
ProxyPass和ProxyPassReverse规则,是否存在覆盖这些端点的错误配置。例如,如果配置了将所有请求转发到Spring的DispatcherServlet,可能会跳过Vaadin Servlet的处理。 - 若使用了URL重写模块(mod_rewrite),确认没有将
/HEARTBEAT或/PUSH路径重写为其他地址。 - 验证Apache是否支持WebSocket代理:如果Push使用WebSocket传输,需要确保
mod_proxy_wstunnel模块已启用,并且配置了ProxyPass /PUSH ws://your-tomcat-host:8080/PUSH这类规则,否则会降级为long-polling且可能路径出错。
2. 检查Tomcat中Vaadin Servlet的映射配置
从日志中看到跳过自动Servlet注册,因为已存在名为springServlet的Vaadin Servlet,需要确认这个Servlet的映射是否正确:
- 查看
web.xml或Spring Boot配置中,Vaadin Servlet的url-pattern是否设置为/*。如果映射范围过小,会导致/HEARTBEAT这类端点无法被Vaadin Servlet处理。 - 检查是否有其他Servlet或Filter(比如Spring MVC的DispatcherServlet)的映射优先级高于Vaadin Servlet,导致请求被提前拦截。例如,如果DispatcherServlet映射了
/*,需要确保Vaadin的特殊端点被排除在Spring路由之外。 - 直接访问Tomcat的端口(绕过Apache),测试
POST /HEARTBEAT/?v-uiId=1和GET /PUSH?...请求是否返回200。如果正常,说明问题完全在Apache代理层;如果仍然404,则需要排查Tomcat内部的Servlet配置。
3. 验证Vaadin Push与Atmosphere配置
你的主视图使用了@Push(value = PushMode.MANUAL),生产环境可能存在Push传输的适配问题:
- 检查Atmosphere的初始化日志,确认
PushAtmosphereHandler是否正确映射到/*(日志中已显示映射到上下文路径: /*,这部分是正常的)。 - 检查生产环境是否传递了正确的反向代理头(比如
X-Forwarded-Proto、X-Forwarded-Host),Vaadin需要这些头来识别正确的请求路径和协议,否则可能生成错误的Push端点地址。 - 尝试临时将Push模式改为
PushMode.AUTOMATIC,看是否能缓解问题,排除手动Push的配置差异。
4. 排查Spring与Vaadin的路由冲突
如果项目是Spring Boot集成Vaadin,可能存在Spring路由拦截Vaadin内部端点的情况:
- 检查是否有Spring MVC的
@Controller或@RequestMapping拦截了/HEARTBEAT或/PUSH路径,这类自定义路由会覆盖Vaadin的内部处理。 - 查看Vaadin的路由配置,确认没有自定义的
Route或RouteAlias占用了这些内部端点路径。 - 检查Spring Security配置,如果启用了CSRF保护,需要确保
/HEARTBEAT和/PUSH路径被允许绕过CSRF验证,否则请求会被拦截。
5. 临时缓解OOM问题
在排查根源的同时,可以先减少错误日志的生成,避免OOM快速发生:
- 调整日志级别,将
com.vaadin.flow.router.RouteNotFoundError的日志级别从INFO改为WARN或ERROR,减少日志输出量。 - 检查生产环境的日志滚动配置,确保日志文件能及时归档,避免占用过多磁盘和内存。
快速验证步骤
- 绕过Apache,直接访问Tomcat的8080端口,测试核心端点的返回状态;
- 对比新旧应用的Apache代理配置,复制旧应用中针对Vaadin端点的转发规则到新配置;
- 确认Vaadin Servlet的映射覆盖所有路径,且没有被Spring或其他Servlet拦截。
内容的提问来源于stack exchange,提问作者Stellis
相关产品推荐
相关产品推荐

