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

时间:2016-07-22 12:35:53

标签: java jersey

道歉:我没有一个简单的测试用例来重现这个问题,因为它非常间歇性地发生。但是,我非常感谢有关如何开始诊断问题的一些帮助。

我在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流的响应对象)。

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

注意:

  • 对于SSE流,我总是在写入之前检查EventOutput是否未关闭
  • 写入AsyncResponse个对象时,我总是先检查isSuspended()(并注入@Suspended注释)

同样,任何提示或指示都会有如此大的帮助。我的想法已经用完了!

1 个答案:

答案 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)。