Netty Socket压测报:Address already in use: no further information


最近左羊在做Netty Socket压力测试时,客户端连接数每次加压到4千左右时便会报出上述错误,特以此文记录下原因及解决方案。
环境介绍
Windows 10JDK 1.8Netty 4.1.18.Final
代码示例
服务端
package cn.zy.testoneconnectionsnumber.netty_socket_server;import cn.zy.testoneconnectionsnumber.ConvertCode;import io.netty.bootstrap.ServerBootstrap;import io.netty.channel.*;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.SocketChannel;import io.netty.channel.socket.nio.NioServerSocketChannel;import io.netty.handler.codec.LengthFieldBasedFrameDecoder;import io.netty.handler.codec.LengthFieldPrepender;import io.netty.handler.codec.bytes.ByteArrayDecoder;import io.netty.handler.codec.bytes.ByteArrayEncoder;import io.netty.handler.codec.string.StringDecoder;import io.netty.handler.codec.string.StringEncoder;import io.netty.util.CharsetUtil;import io.netty.util.concurrent.DefaultThreadFactory;public class NettyServer {public static void main(String[] args) {NioEventLoopGroup bossGroup = new NioEventLoopGroup(1, new DefaultThreadFactory("Server1", true));NioEventLoopGroup wokerGroup = new NioEventLoopGroup(1, new DefaultThreadFactory("Server1", true));try{ServerBootstrap bootstrap = new ServerBootstrap();bootstrap.group(bossGroup,wokerGroup).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel socketChannel) throws Exception {ChannelPipeline pipeline = socketChannel.pipeline();pipeline.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE,0,4,0,4));pipeline.addLast(new LengthFieldPrepender(4));pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8));pipeline.addLast(new SimpleChannelInboundHandler<String>() {@Overrideprotected void channelRead0(ChannelHandlerContext channelHandlerContext, String msg) throws Exception {System.out.println(msg);channelHandlerContext.channel().writeAndFlush("Hello Netty Clinet!");}});}});//绑定端口号ChannelFuture channelFuture = bootstrap.bind(9999).sync();channelFuture.channel().closeFuture().sync();} catch (InterruptedException e) {e.printStackTrace();} finally {bossGroup.shutdownGracefully();wokerGroup.shutdownGracefully();}}}
客户端
package cn.zy.testoneconnectionsnumber.netty_socket_client;import io.netty.bootstrap.Bootstrap;import io.netty.channel.*;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.SocketChannel;import io.netty.channel.socket.nio.NioSocketChannel;import io.netty.handler.codec.LengthFieldBasedFrameDecoder;import io.netty.handler.codec.LengthFieldPrepender;import io.netty.handler.codec.string.StringDecoder;import io.netty.handler.codec.string.StringEncoder;import io.netty.util.CharsetUtil;import io.netty.util.concurrent.DefaultThreadFactory;import java.time.LocalDateTime;public class NettyClient {public static void main(String[] args) {NioEventLoopGroup eventLoopGroup = new NioEventLoopGroup(1, new DefaultThreadFactory("client1", true));for (int i = 0; i < 6000; i++) {int finalI = i;Bootstrap bootstrap = new Bootstrap();bootstrap.group(eventLoopGroup).channel(NioSocketChannel.class).handler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel socketChannel) throws Exception {ChannelPipeline pipeline = socketChannel.pipeline();pipeline.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4));pipeline.addLast(new LengthFieldPrepender(4));pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8));pipeline.addLast(new SimpleChannelInboundHandler<String>() {@Overrideprotected void channelRead0(ChannelHandlerContext channelHandlerContext, String msg) throws Exception {System.out.println(msg);channelHandlerContext.writeAndFlush(LocalDateTime.now());channelHandlerContext.close();}@Overridepublic void channelActive(ChannelHandlerContext channelHandlerContext) throws Exception {channelHandlerContext.writeAndFlush(finalI + "Hello Netty Server!");}});}});try {ChannelFuture channelFuture = bootstrap.connect("localhost", 9999).sync();channelFuture.channel().closeFuture().sync();} catch (InterruptedException e) {e.printStackTrace();}}}}
造成原因
原因是Windows的默认最大TCP连接端口数(MaxUserPort)是5000,默认240秒释放之前的操作完的等待线程。由此造成本机开发环境压力测试,连接数达到3-4千时报错。
解决步骤
1、打开注册表:regedit(开始-运行-输入regedit,win+R - 输入regedit)。2、\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters。3、新建 DWORD值,name:TcpTimedWaitDe,value:30(十进制) –> 设置为30秒,默认是240秒。4、新建 DWORD值,name:MaxUserPort,value:65534(十进制) –> 设置最大连接数65534,Windows的默认最大TCP连接端口数(MaxUserPort)是5000。5、重启系统。
参考文献
码农教程 . http://www.manongjc.com/detail/27-wgzlsxgoyaywiiz.html . 超出TCP连接端口数限制(MaxUserPort)引起的服务器问题博客园 . https://www.cnblogs.com/ngd-mzl/p/16409901.html . jmeter 性能测试 报错信息“address already in use:connect”解决方法张彦飞 . 深入理解Linux网络 . 第八章 一台机器最多支持多少条TCP链接
文章转载自左羊公社,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




