关于使用netty进行通讯连接时连接断开重连的错误实践

问题

线上监控发现某个服务所在的容器CPU使用率很高,内存也不低。

问题排查

1.使用top指令查看是什么进程的CPU使用率最高,发现是java进程,再使用top -Hp对进程内的线程进行监控,查看是那些线程的CPU使用率那么高。执行指令后得出几个异常的数据值:1.线程数有一千多个,2.有九个线程的CPU使用率一直很高。
2. 使用jstack导出java进程的栈信息,根据步骤1中CPU使用率高的线程id在导出文件中找出具体的java线程,结果发现CPU使用率高的线程都是GC线程,由此初步判断是因为创建了大量的难以回收的对象。
3. 接着结合业务日志,发现连接一直不稳定,连接后立马又断开了,由此想到代码中确实有处理断开重连的逻辑处理。打开项目查看处理"断开重连"部分的代码,发现断开后是创建一个Thread对象进行重连操作。于是进一步判断是因为反复重连一直创建Thread对象。
4.本地开启服务重复重连操作,打开资源管理器跟踪内存和CPU使用情况,结合JVisualVM,发现老年代基本上每次回收都没有收获,而线程信息中,nio-event-loop-group-xxx尽然是最多的,执行时间也很长。此时发现跟步骤3得出的判断不一样,然后上网搜索关于此线程的知识,再跟踪源码,发现这个线程是在使用netty框架进行连接时new NioEventLoopGroup()生成的,该操作实质是创建线程池。对比代码发现断开重连时每次都执行了new NioEventLoopGroup()操作,问题的原因得到确认。附上netty客户端初始化的常规代码:

        EventLoopGroup group = new NioEventLoopGroup();
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(group).channel(NioSocketChannel.class)
                .option(ChannelOption.TCP_NODELAY, true)
                .handler(new ChannelInitializer<SocketChannel>() {
					//处理器
				};
		//bootstrap.connect(ip,port);

总结

使用框架时,虽然官方有demo指引,但是要想处理复杂的情况,还是得先弄懂原理。查看源码,知道每一步都是要做什么的,才能做到“心中有数”。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值