netty tcp连接 出现大量CLOSE_WAIT
LAST_ACK 5
SYN_RECV 2
CLOSE_WAIT 2
ESTABLISHED 863
FIN_WAIT1 22
FIN_WAIT2 106
TIME_WAIT 4698
在ESTABLISHED 达到2000,CLOSE_WAIT逐步增高### 问题描述
服务器 阿里云 4核16G, 运行时跑不满
相关代码
@Slf4j
@Component
public class NettyServer {
private EventLoopGroup bossGroup;
private EventLoopGroup workerGroup;
@Autowired
private NettyServerConfig nettyServerConfig;
public void start() {
//bossGroup线程池用来接受客户端的连接请求
bossGroup = new NioEventLoopGroup();
//workerGroup线程池用来处理boss线程池里面的连接的数据
workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup, workerGroup);
serverBootstrap.channel(NioServerSocketChannel.class);
serverBootstrap.childHandler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) throws Exception {
ch.pipeline().addLast(new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN,Integer.MAX_VALUE,0,4,2,4,true));
ch.pipeline().addLast(new IdleStateHandler(600, 600, 600, TimeUnit.SECONDS));//心跳600秒检测一次
ch.pipeline().addLast("handler", new NettyServerHandler());
}
});
serverBootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);//检测客户端连接是否有效的参数
ChannelFuture f = serverBootstrap.bind(nettyServerConfig.getPort()).sync();
if(f.isSuccess()){
log.info("TCP Server Start Success------Port---【" + nettyServerConfig.getPort() + "】");
f.channel().closeFuture().sync();
} else {
log.error("TCP Server Start Failed------Port---【" + nettyServerConfig.getPort() + "】");
}
} catch (Exception e) {
log.error("======nettyserver stop======", e);
stop();
}
}
public void stop(){
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
@Slf4j
@Service
public class NettyServerHandler extends ChannelInboundHandlerAdapter {
/**
* channelAction
*
* 当客户端主动链接服务端的链接后,这个通道就是活跃的了。也就是客户端与服务端建立了通信通道并且可以传输数据
*
*/
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
//设置连接时间
Channel channel = ctx.channel();
//加入定时清除任务
NettyChannelManager.addTimeClear(channel);
}
/**
* 当客户端主动断开服务端的 链接后,这个通道就是不活跃的。也就是说客户端与服务端的关闭了通信通道并且不可以传输数据
*/
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
try {
Integer roomNumber = NettyChannelUtil.getRoomNumber(ctx.channel());
if (roomNumber != null) {
//退出房间
GameNavigation gameNavigation = SpringContextHolder.getBean(GameNavigation.class);
gameNavigation.exitRoom(ctx.channel());
}
} catch (Exception e) {
log.error("channelInactive Exception", e);
}
}
/**
* @param ctx
* @param msg
* @throws Exception
*/
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
ByteBuf byteBuf = (ByteBuf) msg;
try {
int code = ByteBufUtil.readShort(byteBuf);
byte[] bytes = ByteBufUtil.readBytes(byteBuf);
GameNavigation gameNavigation = SpringContextHolder.getBean(GameNavigation.class);
RoomProducer roomRequest = new RoomProducer();
roomRequest.sendRoomRequest(code,bytes);
gameNavigation.navigation(ctx.channel(), code, bytes);
}catch (Exception e){
log.error("channelRead Exception", e);
} finally {
byteBuf.release();
}
}
/*
* exceptionCaught
*
* exception 异常
* Caught 抓住
*
* 抓住异常,当发生异常的时候,可以做一些相应的处理,比如打印日志、关闭链接
*
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception
{
try{
if(cause.getClass() != IOException.class)
{
cause.printStackTrace();
// close();
}
}catch (Exception e){
e.printStackTrace();
}
}
/**
* 监听用户超时
*/
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
}
}
你期待的结果是什么?实际看到的错误信息又是什么?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论