Netty高可靠性设计:优化建议
尽管Netty的可靠性已经做得非常出色,但是在生产实践中还是发现了一些待优化点,本小节将进行简单说明。希望后续的版本中可以解决,当然用户也可以根据自己的实际需要决定自行优化。
1 发送队列容量上限控制
Netty的NIO消息发送队列ChannelOutboundBuffer并没有容量上限控制,它会随着消息的积压自动扩展,直到达到0x7fffffff。
如果网络对方处理速度比较慢,导致TCP滑窗长时间为0;或者消息发送方发送速度过快,或者一次批量发送消息量过大,都可能会导致ChannelOutboundBuffer的内存膨胀,这可能会导致系统的内存溢出。
建议优化方式如下:在启动客户端或者服务端的时候,通过启动项的ChannelOption设置发送队列的长度,或者通过-D启动参数配置该长度。
2 回推发送失败的消息
当网络发生故障的时候,Netty会关闭链路,然后循环释放待未发送的消息,最后通知监听listener。
这样的处理策略值得商榷,对于大多数用户而言,并不关心底层的网络I/O异常,他们希望链路恢复之后可以自动将尚未发送的消息重新发送给对方,而不是简单的销毁。
Netty销毁尚未发送的消息,用户可以通过监听器来得到消息发送异常通知,但是却无法获取原始待发送的消息。如果要实现重发,需要自己缓存消息,如果发送成功,自己删除,如果发送失败,重新发送。这对于大多数用户而言,非常麻烦,用户在开发业务代码的同时,还需要考虑网络I/O层的异常并为之做特殊的业务逻辑处理。
下面我们看下Mina的实现,当发生链路异常之后,Mina会将尚未发送的整包消息队列封装到异常对象中,然后推送给用户Handler,由用户来决定后续的处理策略。相比于Netty的“野蛮”销毁策略,Mina的策略更灵活和合理,由用户自己决定发送失败消息的后续处理策略。
大多数场景下,业务用户会使用RPC框架,他们通常不需要直接针对Netty编程,如果Netty提供了发送失败消息的回推功能,RPC框架就可以进行封装,提供不同的策略给业务用户使用,例如:
1.缓存重发策略:当链路发生异常之后,尚未发送成功的消息自动缓存,待链路恢复正常之后重发失败的消息;
2.失败删除策略:当链路发生异常之后,尚未发送成功的消息自动销毁,它可能是非重要消息,例如日志消息,也可能是由业务直接监听异常并做特殊处理;
3.其他策略.......
最新文章
- iOS - NSMutableAttributedString富文本的实现
- 加密算法中BASE64、MD5、SHA、HMAC等之间的区别
- Ternary Expression Parser
- github for window的代理设置方法
- .NET RSACryptoServiceProvider PEM + DER Support
- 20145102 《Java程序设计》第3周学习总结
- asp.net 中使用JQuery Ajax 上传文件
- 【网络流24题】No. 17 运输问题 (费用流)
- 使用URL创建网络连接、网络流的阻塞问题
- MFC获取当前时间
- Sass嵌套
- spring mvc 之@requestmapping
- sysbench的框架实现介绍
- 四大解析器(BeautifulSoup、PyQuery、lxml、正则)性能比较
- 【题解】Luogu P4436 [HNOI/AHOI2018]游戏
- TCP协议和UDP协议下的socket
- 与python的三天
- servlet和jsp概述
- CS229 6.8 Neurons Networks implements of PCA ZCA and whitening
- ListView高效分页