道歉:我没有一个简单的测试用例来重现这个问题,因为它非常间歇性地发生。但是,我非常感谢有关如何开始诊断问题的一些帮助。
我在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
个对象时,我总是先检查isSuspended()
(并注入@Suspended
注释)同样,任何提示或指示都会有如此大的帮助。我的想法已经用完了!
答案 0 :(得分:0)
经过大量研究后,我得出结论,我的问题必定(当然)是用户错误,即使我从等式中删除apache代理时无法重现错误。就我而言,在将EventOutputs视为已关闭时,我必须更加小心 - 因为您只能在尝试写入时判断连接是否已打开。总的来说,我的发现是:
当您继续引用响应对象,然后在Tomcat将其重新用于其他请求后写入它们时,会发生此类错误。这可以是例如您需要保留的AsyncResponse或EventOutput对象,以便以后恢复或写入。
但是,如果这是一个难以追踪并且您需要解决方案的错误,那么有一个Tomcat设置将以性能为代价禁用这些对象的重用,如下所示:{{3 }}
设置
org.apache.catalina.connector.RECYCLE_FACADES
系统属性 为true将导致为每个请求创建一个新的Facade对象。 这减少了应用程序暴露数据的机会 一个请求到另一个。
(不要被名称混淆; RECYCLE_FACADES=true
表示外墙将不重新使用,新的将在需要时创建。
有https://tomcat.apache.org/tomcat-8.0-doc/security-howto.html这样的应用程序错误只会在apache代理后面出现,所以如果你直接访问Tomcat就会消失,这并不一定意味着apache有问题。
正如我所说,这不太可能是由Tomcat,Apache或mod_proxy_ajp中的错误引起的...但如果你是一个不幸的人,你可以尝试使用另一个连接器(例如mod_jk)。