【问题标题】:Netty - connectTimeoutMillis vs. ReadTimeoutHandlerNetty - connectTimeoutMillis 与 ReadTimeoutHandler
【发布时间】:2012-11-15 01:41:22
【问题描述】:
来自 Netty API 文档
connectTimeoutMillis = "连接超时,以毫秒为单位。如果禁用,则为 0。"
和
ReadTimeoutHandler = 在一定时间内没有读取数据时引发 ReadTimeoutException。
从客户的角度来看,我对上述内容的解释是否正确?
客户端将尝试连接到主机直到“connectTimeoutMillis”。如果建立了连接,并且未将 ReadTimeoutHandler 添加到管道中,则 Channel 可以无限期地等待响应。如果向管道添加了 ReadTimeoutHandler,则一旦 timeoutSeconds 过去,就会引发 ReadTimeoutException。
一般来说,我只想尝试连接到主机最多“x”秒,但如果通过网络发送请求,我希望最多等待“y”秒回复。如果它塑造/影响答案,则客户端是 Netty,但服务器不是。
跟进:ReadTimeoutHandler 上的 timeoutSeconds 是连续读取字节之间的超时,还是整个请求/响应的超时?示例:如果 timeoutSeconds 为 60,并且每 59 秒读取一个字节(总共 1024 个字节),那么整个响应会在 60416 秒内成功读取,还是会因为总经过时间超过 60 秒而失败?
【问题讨论】:
标签:
java
netty
connection-timeout
【解决方案1】:
ReadTimeoutHandler 不理解响应的概念。它只能理解 Netty 3 中的 messageReceived 事件或 Netty 4 中的 inboundBufferUpdated 事件。从 NIO 的角度来看,此行为的确切影响取决于 ReadTimeoutHandler 在管道中的位置。 (我从未使用过 OIO,所以不能说行为是否完全相同)。
如果 ReadTimeoutHandler 低于管道中的任何帧解码器(即更靠近网络),那么您描述的行为是正确的 - 单字节读取将重置计时器,并且正如您所确定的,可能导致响应很长一段时间要读。如果您正在编写服务器,则可以利用它来形成拒绝服务攻击,而攻击者只需付出很少的努力。
如果 ReadTimeoutHandler 高于您的帧解码器,则它适用于您的整个响应。我认为这是您正在寻找的行为。
请注意,ReadTimeoutHandler 也不知道您是否发送了请求 - 它只关心是否已从套接字读取数据。如果您的连接是持久的,并且您只想在发送请求时触发读取超时,则需要构建一个请求/响应感知超时处理程序。
【解决方案2】:
-
是的,您已正确识别出连接超时和读取超时之间的区别。请注意,无论任何文档可能有相反的说法,默认或零连接超时意味着大约 60-70 秒,而不是无穷大,您只能使用连接超时参数来减少该默认值,而不是增加它。
读取超时在您调用 read() 时开始,并在超时或数据到达时结束。这是 read() 可以阻塞等待第一个字节到达的最长时间。它不会在一次调用中再次阻塞。