HTTP2服务器发送FIN / ACK然后RST没有大量流量

时间:2017-07-27 16:09:18

标签: tcp jersey http2

我在HTTP2上使用Jersey。当流量变得有点高时,就会出现异常。我得到了pcap发现服务器发送FIN / ACK而没有收到FIN。我不确定它是从服务器端关闭连接的单个FIN。或单个FIN将ACK组合到先前的数据包。它看起来是后者,因为客户端没有发送FIN。所以问题是为什么服务器只在很小的流量下发送FIN。我发现rece_q和send_q非常低。 CPU使用率不是很高。我已经调整了一些TCP参数,结果是一样的。这种行为是不稳定的,有时它还可以,有时候不行。当我添加更多请求(具有相同的TPS)时,则不行。它看起来服务器完成了连接,但不知道确切的原因。它与HTTP2有关吗?我们有一些地方可以看到确切的原因吗​​?

以下是pcap快照。

pcap snapshot

更新2017-07-30 调试日志:

Sun Jul 30, 2017 8:31:35.591 PM org.glassfish.grizzly.http2.Http2FrameCodec parse
FINE: Rx [2]: connection=TCPNIOConnection{localSocketAddress={localhost/127.0.0.1:80}, peerSocketAddress={/127.0.0.1:57802}}, frame=DataFrame {streamId=277, type=0, flags=[none], length=42, data=BuffersBuffer (154351355) [pos=0 lim=42 cap=42 bufferSize=1 buffers=[HeapBuffer (165674143) [pos=0 lim=42 cap=8391], null, null, null]]}
Sun Jul 30, 2017 8:31:35.673 PM org.glassfish.grizzly.http2.Http2BaseFilter processFrames
FINE: Http2ConnectionException occurred on connection=TCPNIOConnection{localSocketAddress={localhost/127.0.0.1:80}, peerSocketAddress={/127.0.0.1:57802}} during Http2Frame processing
Sun Jul 30, 2017 8:31:35.684 PM org.glassfish.grizzly.http2.Http2FrameCodec serializeAndRecycle
FINE: Tx: connection=TCPNIOConnection{localSocketAddress={localhost/127.0.0.1:80}, peerSocketAddress={/127.0.0.1:57802}}, frame=GoAwayFrame {streamId=0, type=7, flags=[none], length=64{lastStreamId=199, errorCode=REFUSED_STREAM}

pcap快照中的流277

pcap contains stream 277 from No 270,271 and 272

269包中有一个SETTINGS包。发送SETTINGS在运输过程中是否正常?在269之后,有三个包270,271和272正在使用蒸汽277.

奇怪的是,在8:31:35.684左右,我没有找到GOWAY包。但仅在8:31:36.035中发送RST / ACK。在圆形时,调试日志如下:

Sun Jul 30, 2017 8:31:36.020 PM org.glassfish.grizzly.http2.Http2FrameCodec parse
FINE: Rx [2]: connection=TCPNIOConnection{localSocketAddress={localhost/127.0.0.1:80}, peerSocketAddress={/127.0.0.1:57802}}, frame=DataFrame {streamId=465, type=0, flags=[END_STREAM], length=0, data=ByteBufferWrapper (1101850112) [visible=[java.nio.HeapByteBuffer[pos=0 lim=0 cap=0]]]}
Sun Jul 30, 2017 8:31:36.023 PM org.glassfish.grizzly.http2.Http2BaseFilter processDataFrame
FINE: Data frame received for non-existent stream: connection=TCPNIOConnection{localSocketAddress={localhost/127.0.0.1:80}, peerSocketAddress={/127.0.0.1:57802}}, frame=DataFrame {streamId=277, type=0, flags=[END_STREAM], length=0, data=ByteBufferWrapper (1101850112) [visible=[java.nio.HeapByteBuffer[pos=0 lim=0 cap=0]]]}, stream=277
Sun Jul 30, 2017 8:31:36.024 PM org.glassfish.grizzly.http2.Http2BaseFilter processFrames
FINE: Http2StreamException occurred on connection=TCPNIOConnection{localSocketAddress={localhost/127.0.0.1:80}, peerSocketAddress={/127.0.0.1:57802}} during Http2Frame processing
Sun Jul 30, 2017 8:31:36.025 PM org.glassfish.grizzly.http2.Http2BaseFilter processFrames
FINE: Http2ConnectionException occurred on connection=TCPNIOConnection{localSocketAddress={localhost/127.0.0.1:80}, peerSocketAddress={/127.0.0.1:57802}} during Http2Frame processing

日志显示收到一条不存在的流277.该流正好是第一个日志中记录的流。不确定这个蒸汽277会在接下来的几个毫秒内引起RST / ACK。我认为它应该对数据包269~272和流277有一些问题。

顺便说一下,这次没有FIN / ACK。

1 个答案:

答案 0 :(得分:0)

pcap显示服务器上的异常终止。

您应该检查服务器日志,了解发生这种情况的详细信息。

一个可能的原因是服务器错误。

另一个可能的原因是客户端在数据包14发送了无效的HEADERS帧;仍然,服务器应发送GOAWAY帧,而不仅仅是关闭连接。

数据包17的RST是正常的,因为客户端在处理HEADERS之前在数据包16发送了FIN帧,因此服务器回复了RST指示发送的数据没有进入用户代码层。

服务器日志(可能是DEBUG级别)应该告诉你更多关于发生了什么的事情。