记一次windows下Netty做为压测端引发的错误 No buffer space available (maximum connections reached?): bind

2023-11-17

最近写了个客户端压测工具结果每次压到将近5000时就会报错,也是搞了两天才发现问题,主要是错误表现和网上大多数人的表现一样,导致忽略了眼前的错误提示

错误表现具体如下:

java.lang.IllegalStateException: failed to create a child event loop
    at io.netty.util.concurrent.MultithreadEventExecutorGroup.<init>(MultithreadEventExecutorGroup.java:88)
    at io.netty.util.concurrent.MultithreadEventExecutorGroup.<init>(MultithreadEventExecutorGroup.java:58)
    at io.netty.channel.MultithreadEventLoopGroup.<init>(MultithreadEventLoopGroup.java:52)
    at io.netty.channel.nio.NioEventLoopGroup.<init>(NioEventLoopGroup.java:87)
    at io.netty.channel.nio.NioEventLoopGroup.<init>(NioEventLoopGroup.java:82)
    at io.netty.channel.nio.NioEventLoopGroup.<init>(NioEventLoopGroup.java:63)
    at io.netty.channel.nio.NioEventLoopGroup.<init>(NioEventLoopGroup.java:51)
    at io.netty.channel.nio.NioEventLoopGroup.<init>(NioEventLoopGroup.java:43)
    at com.sy599.game.server.ClientServer.connect(ClientServer.java:30)
    at com.sy599.game.client.base.Client0.connect(Client0.java:123)
    at com.sy599.game.client.base.Client0.<init>(Client0.java:68)
    at com.sy599.game.client.MatchClient.<init>(MatchClient.java:70)
    at com.sy599.game.test.match.ClientBatchTest.lambda$batchLoginAndMatchTest$4(ClientBatchTest.java:160)
    at com.sy599.game.test.match.ClientBatchTest.lambda$batchInvoke$1(ClientBatchTest.java:38)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: io.netty.channel.ChannelException: failed to open a new selector
    at io.netty.channel.nio.NioEventLoop.openSelector(NioEventLoop.java:175)
    at io.netty.channel.nio.NioEventLoop.<init>(NioEventLoop.java:149)
    at io.netty.channel.nio.NioEventLoopGroup.newChild(NioEventLoopGroup.java:127)
    at io.netty.channel.nio.NioEventLoopGroup.newChild(NioEventLoopGroup.java:36)
    at io.netty.util.concurrent.MultithreadEventExecutorGroup.<init>(MultithreadEventExecutorGroup.java:84)
    ... 16 more
Caused by: java.io.IOException: Unable to establish loopback connection
    at sun.nio.ch.PipeImpl$Initializer.run(PipeImpl.java:94)
    at sun.nio.ch.PipeImpl$Initializer.run(PipeImpl.java:61)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.nio.ch.PipeImpl.<init>(PipeImpl.java:171)
    at sun.nio.ch.SelectorProviderImpl.openPipe(SelectorProviderImpl.java:50)

    at java.nio.channels.Pipe.open(Pipe.java:155)
    at sun.nio.ch.WindowsSelectorImpl.<init>(WindowsSelectorImpl.java:127)
    at sun.nio.ch.WindowsSelectorProvider.openSelector(WindowsSelectorProvider.java:44)
    at io.netty.channel.nio.NioEventLoop.openSelector(NioEventLoop.java:173)
    ... 20 more
Caused by: java.net.SocketException: No buffer space available (maximum connections reached?): bind
    at sun.nio.ch.Net.bind0(Native Method)
    at sun.nio.ch.Net.bind(Net.java:433)
    at sun.nio.ch.Net.bind(Net.java:425)
    at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223)
    at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
    at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:67)
    at sun.nio.ch.PipeImpl$Initializer$LoopbackConnector.run(PipeImpl.java:121)
    at sun.nio.ch.PipeImpl$Initializer.run(PipeImpl.java:76)
    ... 28 more
java.lang.IllegalStateException: failed to create a child event loop
    at io.netty.util.concurrent.MultithreadEventExecutorGroup.<init>(MultithreadEventExecutorGroup.java:88)
    at io.netty.util.concurrent.MultithreadEventExecutorGroup.<init>(MultithreadEventExecutorGroup.java:58)
    at io.netty.channel.MultithreadEventLoopGroup.<init>(MultithreadEventLoopGroup.java:52)
    at io.netty.channel.nio.NioEventLoopGroup.<init>(NioEventLoopGroup.java:87)
    at io.netty.channel.nio.NioEventLoopGroup.<init>(NioEventLoopGroup.java:82)

核心代码如下:(每个新建的连接都会走上此处)

ClientHandler clientHandler = new ClientHandler(client);
EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
final Bootstrap bootstrap = new Bootstrap();
clientHandler.getClient().setEventLoopGroup(eventLoopGroup);
clientHandler.getClient().setBootstrap(bootstrap);
bootstrap.group(eventLoopGroup);
bootstrap.channel(NioSocketChannel.class);
bootstrap.option(ChannelOption.SO_REUSEADDR, true);

上网搜资料: 答案都大同小异,也没有考虑到自己代码层面有问题  总结网上的各个参数如下

注册表 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
变更结果:
MaxUserPort 65534
TCPTimedWaitDelay 30
TcpNumConnections 0xfffffe
UseDomainNameDevolution 1

netsh int ipv4 show dynamicportrange tcp
执行结果:
协议 tcp 动态端口范围
---------------------------------
启动端口        : 1025
端口数          : 64510

虚拟内存空间分配自定义数据  4096~40960 

以上数据更改后依然不行

最终发现 这个错误结果居然会变更  有两种结果  但是后来没有重现出来 就不上错误提示了

java.net.SocketException: No buffer space available (maximum connections reached?): bind

java.net.SocketException: No buffer space available (maximum connections reached?): connect

第一种报错 基本上是服务端最大端口限制出问题了 

第二种报错 是客户端最大端口限制出问题了 最后根据错误提示找到 更改后代码片段 问题解决

static EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
()->{
    ClientHandler clientHandler = new ClientHandler(client);
    final Bootstrap bootstrap = new Bootstrap();
    clientHandler.getClient().setEventLoopGroup(eventLoopGroup);
    clientHandler.getClient().setBootstrap(bootstrap);
    bootstrap.group(eventLoopGroup);
    bootstrap.channel(NioSocketChannel.class);
    bootstrap.option(ChannelOption.SO_REUSEADDR, true);
}

结论:

1.当出现此类错误时不要盲目的修改, 先看清楚错误提示

2.重复创建EventLoopGroup会导致30倍左右当前tcp有效连接被占用

3.netstat -an |find /c "ESTABLISHED" 和 netstat -an |find /c "TIME_WAIT" 是个好东西    

EventLoopGroup 相关解释: https://www.cnblogs.com/magexi/p/10222644.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

记一次windows下Netty做为压测端引发的错误 No buffer space available (maximum connections reached?): bind 的相关文章

随机推荐