Нетты не закрывают каналы нормально - PullRequest
2 голосов
/ 15 января 2012

Я новичок с Нетти.Сейчас мигрирует мой сервер, причина высоких нагрузок.Я читаю много людей, делаю все как в примерах, но у меня есть ошибка: загрузка ЦП растет со временем и очень быстро.

Анализ кучи и журналов показывает мне, что каналы, которые выдают исключения (могут быть не толькоони) не закрываются нормально, и остаются в селекторах работника.Я получил 150+ открытых каналов с 50 пользователями онлайн.

Мой код следующий:

Создание сервера:

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));

Фабрика конвейеров:

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

Декодер:

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;
}
}

И обработчик:

@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();
}

Все работает очень хорошо, кроме растущей загрузки процессора ...

...