泽西岛回复包含不正确的数据

问题描述:

道歉:我没有一个简单的测试用例来重现这个问题,因为它非常间歇地发生。但是,如果甚至开始诊断问题,我将不胜感激。泽西岛回复包含不正确的数据

我有一个在Tomcat上运行的Jersey服务器。

当客户端发出请求时,有时来自完全不同请求的响应会混入正确的响应中。

“正确的”请求可以是任何类型的,但混入的“坏”响应始终来自SSE流(EventOutput)或AsyncResponse。

例如,这是通过正常的请求由客户机接收到的输出:

event: message_sent 
id: 1 
data: {"value":"hello world"} 

{"event-id":"13"}event: message_sent 
id: 2 
data: {"value":"hello world"} 

的真正响应{"event-id":"13"}是本...但周围有两个错误SSE事件。

来处理这个请求的方法简单的返回:

return Response.created(uri).entity(eventId).build(); 

所以我不明白,此时不需要的数据被发送(除非Response.created()将返回其已经用于上证所响应对象流)。

服务器日志始终显示正确的输出。但是,我们知道客户端没有错,因为我们使用数据包嗅探器来确认响应格式错误。

注:

  • 对于SSE流,我总是检查书面形式向他们
  • 写入操作时AsyncResponse对象之前,该EventOutput没有关闭,我总是检查isSuspended()第一(和它们与注入@Suspended注释)

再一次,任何提示或指针将是如此的帮助。我已经用完了想法!

经过大量的研究,我得出结论说我的问题必须是(当然)用户错误,即使我从等式中删除了apache代理时无法重现错误。就我而言,在将EventOutputs视为已关闭时,我必须更加小心 - 因为您只能在尝试写入连接时判断连接是否打开。一般来说,我的发现是:

当你保留对响应对象的引用时,会发生这种类型的错误,然后在Tomcat将它们重新用于其他请求后写入它们。这可以是例如AsyncResponse或EventOutput对象,您需要随时恢复或写入。

但是,如果这是这是难以追查一个错误,你需要一个解决方案,有一个Tomcat的设置,这将在性能为代价禁止重新使用这些对象,因为这里说的:https://tomcat.apache.org/tomcat-8.0-doc/security-howto.html

设置org.apache.catalina.connector.RECYCLE_FACADES系统属性 为true将导致为每个请求创建新的外观对象。 这可以减少应用程序将数据从 发送到另一个请求时发生错误的可能性。

(不要被名称相混淆; RECYCLE_FACADES=true意味着,外墙将得到重用,并在需要时新的将获得创建)。

有像这样的应用程序错误examples只在apache代理后面出现,所以如果直接访问Tomcat时该错误消失,并不一定意味着apache出错。

正如我所说,这不太可能是由于Tomcat,Apache或mod_proxy_ajp中的错误引起的......但如果您不幸运行,您可以尝试使用另一个连接器(例如mod_jk)。