Tcp netty面临大量数据包丢失和延迟

Tcp netty面临大量数据包丢失和延迟,tcp,netty,Tcp,Netty,我在Ubuntu上使用Netty3.5.11和JDK1.7,以非常高的频率接收大量的股票价格更新。正在发送的消息格式是JSON。数据是从redis服务器上的topic订阅的。每个符号都有一个订户。通道对象被传递给多个订阅者,并在接收到数据时写入客户端 现在,在2分钟内接收到的数据量约为25000条记录。每个记录大小的平均长度约为500字节 在测试运行期间,由于通道不可写,大约7500/8000条记录被丢弃。 我如何避免这种情况 我还注意到,延迟系统性地增加,导致在长时间之后收到更新。这是在我使用

我在Ubuntu上使用Netty3.5.11和JDK1.7,以非常高的频率接收大量的股票价格更新。正在发送的消息格式是JSON。数据是从redis服务器上的topic订阅的。每个符号都有一个订户。通道对象被传递给多个订阅者,并在接收到数据时写入客户端

现在,在2分钟内接收到的数据量约为25000条记录。每个记录大小的平均长度约为500字节

在测试运行期间,由于通道不可写,大约7500/8000条记录被丢弃。 我如何避免这种情况

我还注意到,延迟系统性地增加,导致在长时间之后收到更新。这是在我使用Bufferedwritehandler避免数据包丢失时发生的

以下是我在引导上设置的选项

executionHandler = new ExecutionHandler(
            new OrderedMemoryAwareThreadPoolExecutor(Runtime.getRuntime().availableProcessors() * 2, 1000000, 10000000, 100,
            TimeUnit.MILLISECONDS));
serverBootStrap.setPipelineFactory(new ChannelPipelineFactory()
    {
        @Override
        public ChannelPipeline getPipeline() throws Exception
        {
            return Channels.pipeline(new PortUnificationServerHandler(getConfiguration(), executionHandler));
        }
    });

    serverBootStrap.setOption("child.tcpNoDelay", true);
    serverBootStrap.setOption("tcpNoDelay", true);
    serverBootStrap.setOption("child.keepAlive", true);
    serverBootStrap.setOption("child.reuseAddress", true);
    //setting buffer size can improve I/O
    serverBootStrap.setOption("child.sendBufferSize", 16777216);
    serverBootStrap.setOption("receiveBufferSize", 16777216);//1048576);
    // better to have an receive buffer predictor 
    serverBootStrap.setOption("receiveBufferSizePredictorFactory", new AdaptiveReceiveBufferSizePredictorFactory(1024, 1024 * 16, 16777216));//1048576));

    //if the server is sending 1000 messages per sec, optimum write buffer water marks will
    //prevent unnecessary throttling, Check NioSocketChannelConfig doc   
    serverBootStrap.setOption("backlog", 1000);
    serverBootStrap.setOption("sendBufferSize", 16777216);//1048576);
    serverBootStrap.setOption("writeBufferLowWaterMark", 1024 * 1024 * 25);
    serverBootStrap.setOption("writeBufferHighWaterMark", 1024 * 1024 * 50);
管道和处理程序类

public class PortUnificationServerHandler extends FrameDecoder
{

}

缓冲写入句柄

   public class MyBufferedWriteHandler extends BufferedWriteHandler
{

订阅服务器类中用于写入数据的函数

 public void writeToClient(Channel pClientChannel, String pMessage) throws IOException
{
    String lMessage = pMessage;
    if (pClientChannel.isWritable())
    {

            lMessage += Constants.RESPONSE_DELIMITER;
            pClientChannel.write(lMessage);

    }
    else
    {
         logger.warn(DroppedCounter++ + " droppped : " + pMessage);
    }
}
我已经实施了我在stackoverflow和其他网站上读到的一些建议,但我没有成功地解决这个问题

请就我遗漏了什么提出建议或建议


谢谢

你还记得是什么导致了这个问题,以及你是如何解决这个问题的吗?谢谢,只是因为我的消费速度太慢了!!我知道这是一个很晚的回复。但是我在很长一段时间后登录并检查了这个问题。:-@SunilThamban这与你的问题无关,但为什么你两个孩子都有。tcpNoDelay和tcpNoDelay设置在引导中。据我所知,child.tcpNoDelay用于服务器,tcpNoDelay用于客户端。
private final AtomicLong bufferSize = new AtomicLong();
final Logger logger = LoggerFactory.getLogger(getClass());


 public MyBufferedWriteHandler() {
     // Enable consolidation by default.
     super(true);
 }

@Override
public void writeRequested(ChannelHandlerContext ctx, MessageEvent e) throws Exception
{
     ChannelBuffer data = (ChannelBuffer) e.getMessage();

    if (e.getChannel().isWritable())
    {
        long newBufferSize = bufferSize.get();
        // Flush the queue if it gets larger than 8KiB.
        if (newBufferSize > 0)
        {
            flush();
            bufferSize.set(0);
        }
        ctx.sendDownstream(e);
    }
    else
    {
        logger.warn( "Buffering data for : " + e.getChannel().getRemoteAddress() );
        super.writeRequested(ctx, e);
        bufferSize.addAndGet(data.readableBytes());
    }
}

@Override
public void channelInterestChanged(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception
{
    if (e.getChannel().isWritable())
    {
        flush();
    }
}
 public void writeToClient(Channel pClientChannel, String pMessage) throws IOException
{
    String lMessage = pMessage;
    if (pClientChannel.isWritable())
    {

            lMessage += Constants.RESPONSE_DELIMITER;
            pClientChannel.write(lMessage);

    }
    else
    {
         logger.warn(DroppedCounter++ + " droppped : " + pMessage);
    }
}