现象
Netty Channel.close()触发channelInactive
此时 channel state isOpen=false, isActive=false, isWritable=false,此时channel不会在接收来至客户端的请求。
但是此时继承于SimpleChannelInboundHandler 的handler的channelRead0还是在不断处理数据包
场景
这一现象是在客户端对服务器压测过程中出现的。具体的压测方案是客户端瞬时发送大量请求,我这边会对请求进行处理,并将处理的结果返回给客户端。
客户端在接受到服务器下发的包后,回复一个确认。
服务器下发一个包后,客户端在3秒内如果没有回复确认的话,服务器会认为客户端已经掉线,将通道关闭。
由于客户端存在的一个miss,导致在压测过程中的某一时刻发现客户端没有及时回复确认,于是服务器调用Channel.close()关闭通道。于是出现了这个现象。
分析
一个channel内的所有消息(包括数据请求以及inactive),都会放在一个接收队列里,并且是按照FIFO处理。客户端发送来大量的请求,这些请求一部分还在队列中的时候出发了Channel.close()。这时候inactive时间被放入接手队列的队尾,导致channel关闭后channelRead0仍然被触发了很多次,在这多次channelRead0函数调用之后,最后执行了inactive()。
所以这个看是奇怪的现象其实是正常的Channel.close()之后处理的一系列数据包是在channel close之前就已经放在channel的接收队列中的,因为channel close之后是不会在接收对端请求的。