问题描述:
使用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,暂时没有发现问题,后续再实验