Netty(四):实现通道的多路复用
来源:互联网 发布:部落冲突龙的升级数据 编辑:程序博客网 时间:2024/05/09 07:36
问题描述:
在进行压测时,一开始很正常,大约在30000次请求之后,错误率达到100%且接口耗时超过3s(人工设定的超时等待时间),查看日志后发现大量的Cannot assign requested address异常。
“Cannot assign requestedaddress”异常是由于Linux分配的客户端连接端口用尽,无法建立socket连接所致,虽然socket正常关闭,但是端口不是立即释放,而是处于TIME_WAIT状态,默认等待60s后才释放。所以也出现了大量的接口超时的现象了。
因为我们在初始化Netty时使用了保活策略(ChannelOption.SO_KEEPALIVE),当长时间通道没有数据交流时,TCP会发送活动探测数据报文来测试通道的连接状态。在代码逻辑中我们在每一次建立与channel的连接时均新建了一个handler对象(即每次都新建一个通道的连接),所以每当有连接请求时都会分配新的通道,最终导致连接端口用尽。
解决方案:
使用对象池技术,当有相应服务连接请求时,我们通过将负责具体通讯的对象进行池化,限制处理每个服务的通道的数目,使通道能够复用。
首先介绍几个概念:
对象池(ObjectPool): 掌管对象的生命周期,获取,激活,验证,钝化,销毁等
池对象(PooledObject): 被创建在池中的对象,自己可以有一些附加信息
池对象工厂(PooledObjectFactory): 池中对象各个生命周期的具体实现,怎么创建,怎么验证,怎么销毁。
对象池化主要用于减少对象在创建和销毁上面的开销,如果是小对象则不需要池化,如果是大对象可以考虑池化,对于像数据库连接、网络之类的重对象来说是很有必要池化的,我们可以根据需求判断,如果创建某种对象成为了影响程序性能的关键因素则需要池化。
在本项目中,使用到的对象池结构框图如下:
本服务中新建了ChanneConnectPoolFactory类作为池对象工厂(PooledObjectFactory),此类继承至BasePooledObjectFactory类,基类中有两个方法需要重写:create()方法及wrap()方法。create方法用于对象的创建,wrap方法用于将创建的对象转化为池对象(PooledObject)。然后建立GenericObjectPool的对象池,并通过GenericObjectPoolConfig设置对象池的相关属性:如,池中最多对象总数,最大空闲数,对象的最长等待时间等。当要建立通道连接时,我们通过borrowChannelHandler方法向对象池中“借”一个对象,在将数据发送给下游服务或者发送出现异常时,我们将之前“借”用的对象再“还”给对象池,从而使连接可以复用。
在发送完数据以后,要判断对象是否有效,将处于有效状态的对象“还”给对象池(如果对象无效时执行return操作,将产生"Object has already beenreturned to this pool or is invalid"异常)。
- Netty(四):实现通道的多路复用
- 【转】使用Netty实现多路复用的client
- select多路复用 : EasyMouse的通道模式设计(上)
- select多路复用 : EasyMouse的通道模式设计(下)
- 基于Netty的RPC简单框架实现(四):Netty实现网络传输
- 四通道和三通道的处理
- linux socket的IO多路复用简单例子(四)
- Netty4 学习笔记之四: Netty HTTP服务的实现
- I/O多路复用的实现
- OpenCV学习笔记(二十一)---三通道和四通道之间的区别
- 基于Python的四通道图像融合(二)
- 基于Python的四通道图像融合(一)
- Java-NIO(四):通道(Channel)的原理与获取
- Linux网络编程(四) select多路复用
- Linux网络编程(四) select多路复用 .
- python socket(四)网络多路复用
- select()函数(I/O多路复用)-并发服务器的实现
- Netty学习之NIO---通道Channel(一)
- poj1741点分治
- settings.xml 文件配置
- 移动机器人入门介绍
- ArcGIS中的土地利用变化分析
- form表单提交
- Netty(四):实现通道的多路复用
- 快捷技巧
- 表单练习
- Typescript学习笔记
- 1004 array array array
- 回朔算法(试探算法)-彩票号码组合
- 上下拉刷新
- 求输入向量的任何连续子向量的最大和
- CentOS7禁用ipv6