线上监控发现某个服务所在的容器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客户端初始化的常规代码:
使用框架时虽然官方有demo指引,但是要想处理复杂的情况还昰得先弄懂原理。查看源码知道每一步都是要做什么的,才能做“心中有数”