问题描述:

使用Netty写了一个服务器和客户端,进行压力测试,客户端for循环启动了5w次,每次发送一定量的数据,但是只成功发送不到1w次,服务器疯狂报错:IOException:你的主机中的软件中止了一个已建立的连接


原因分析:

因为是服务器报的错:你的主机中...,所以在服务器中查找bug(如果是客户端出错,服务器的log应该是:远程主机...

可能是netty服务端配置的参数不足以支撑瞬间的高并发请求(比如SO_BACKLOG设置的不够大?),或者是服务器的硬件不行,加上服务器处理的是需要一定耗时的业务,反正最后它处理不过来了,就将无法处理的连接都关闭了


解决方案:

每次执行完for循环里的语句进行适当的Thread.sleep() 服务器的参数设置后期实验中

-------------------------11.26手动分割线-------------------------

又做了几天实验,发现我前几天得出的结论好蠢。。

先说结论:确实是服务器这边无法支撑那么多连接,就主动断开了一些连接。

但是主要问题还是出在代码的编写上(就想着netty不可能撑不起来几万的连接嘛,我好菜我先说),因为我做的业务比较耗时(收文件-文件处理-发文件),之前以为只有【文件处理】比较耗时,再加上netty文档里面建议不是很耗时的业务就尽量复用ctx.channel().eventLoop(),否则线程的切换开销更大,所以只给【文件处理】的那个handler分配了专门处理的EventExecutorGroup,但其实高并发的情况下【收发文件】也是很耗时的业务,也应该用EventExecutorGroup来处理,否则就会占用服务器专门来处理IO的worker NioEventLoopGroup,就会导致IOException

然后把EventExecutorGroup写成了全局单例的变量,尽量减少每次创建销毁的开销以及OOM的可能

目前这样修改完,客户端跑了30w,暂时没有发现问题,后续再实验