Netty not closing channels normaly

1.4k Views Asked by At

I'm new with Netty. Now migrating my server, cause of high loads. I read lots of mans, doing everything like in examples, but have a bug: CPU load grows in time and very fast.

Analyzing heap and logs shows me, that channels, which throws exceptions (may be not only them) not closing normally, and keeps in worker's selectors. I got 150+ opened channels with 50 users online.

My code is follows.

Creating server:

networkServer = new ServerBootstrap(new NioServerSocketChannelFactory(bossExec, ioExec, 4));
networkServer.setOption("backlog", 500);
networkServer.setOption("connectTimeoutMillis", 10000);
networkServer.setPipelineFactory(new ServerPipelineFactory());
Channel channel = networkServer.bind(new InetSocketAddress(address, port));

Pipeline factory:

@Override
public ChannelPipeline getPipeline() throws Exception {
    PacketFrameDecoder decoder = new PacketFrameDecoder();
    PacketFrameEncoder encoder = new PacketFrameEncoder();
    return Channels.pipeline(decoder, encoder, new PlayerHandler(decoder, encoder));
}

Decoder:

public class PacketFrameDecoder extends FrameDecoder {
@Override
public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
}

@Override
public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
}

@Override
protected Object decode(ChannelHandlerContext arg0, Channel arg1, ChannelBuffer buffer) throws Exception {
    try {
            buffer.markReaderIndex();
        Packet p = // ... doing decoding things
        if(p != null)
            return p;
                    // Reset buffer if not success
        buffer.resetReaderIndex();
            // Reset buffer if not success and got exception of not enough bytes in buffer
    } catch(BufferUnderflowException e) {
        buffer.resetReaderIndex();
    } catch(ArrayIndexOutOfBoundsException aioobe) {
        buffer.resetReaderIndex();
    }
    return null;
}
}

And handler:

@Override
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
    worker = new PlayerWorkerThread(this, e.getChannel());
}

@Override
public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
    worker.disconnectedFromChannel();
}

@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
    if(e.getChannel().isOpen())
        worker.acceptPacket((Packet) e.getMessage());
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
    Server.logger.log(Level.WARNING, "Exception from downstream", e.getCause());
    ctx.getChannel().close();
}

Everything is working very well, except growing cpu load...

0

There are 0 best solutions below