背景:
最近在项目线上出现一些问题,部分拆包粘包数据并没有拆完,就转发给下一个流程,所以导致数据解析失败。在调试的过程中,我发现了一个Netty
神奇的机制——重发机制。
介绍:
Netty重发:Netty中的byteBuf中的数据如果没有被取走,那么会不停的向下层推送byteBuf中的数据。
跟踪源码:
- 1.首先发送一条粘包报文:40 3A 00 29 13 80 94 30 02 7F 01 5A 17 46 02 10 20 10 23 19 00 6C F1 14 38 39 38 36 30 30 44 39 32 37 31 37 35 37 36 38 34 33
33 33 DC 0D 0A 40 3A 00 29 13 80 94 30 02 7F 01 5A 17
(不懂粘包和拆包的小伙伴可戳这里) - 2.首次进入
- 3.拿到半包数据,向下跟踪,这里检测到解码状态,设置为继续等待,所以不移除
- 4.然后跟踪到这个方法,这里判断in是否可读(也就是byteBuf中一直有数据),可读就循环。
- 5.再看这里,判断可读字节是否是上一次长度,推测decode是否解析了报文,很显然这里解析了第一包数据,还剩余半包,所以不执行这里,然后继续while循环。
- 6.于是走到这里,看到了吗?这里就是把剩下半包进行了重发。值得注意的是,他这里只重发一次,因为下次再去检查时,发现readIndex并没有改变,netty就不会再重复发送。
- 7.更神奇的是,Netty在连接关闭时,也会检测是否有剩余报文,并进行重发
思考:
1.Netty 为什么要进行重发呢?
个人思考:我认为是为了保证可靠性,传统思路是客户端给Netty发一条,Netty就向下推送一条,那么如果客户端发送的很快呢,Netty此时并没有识别出来发送了两次,但是两个报文已经存储byteBuf,那么此时就会丢失一条报文,这是万万不可的。包括断开连接时,也把剩余报文再推送一次,目的是:连接要断开了,我还有这么多数据你还没取走了,我在断开连接前再给你推送一遍,保证我的可靠性。
2.联想:
其实在我们工作和生活中,要想做一个可靠的人,亦要如此。