如何使用Java netty正确限制带宽使用?

8

我开发了一个基于Java和netty nio库的下载客户端,并且实现了带宽限制功能。我是通过GlobalTrafficShapingHandler对象来实现这个功能的。根据这个类的JavaDoc,我初始化nio客户端管道如下:

...
trafficHandler = new GlobalTrafficShapingHandler(
        new HashedWheelTimer(), 0, 0, 1000);
execHandler = new ExecutionHandler(
        new OrderedMemoryAwareThreadPoolExecutor(20, 0, 0));
...

public ChannelPipeline getPipeline() throws Exception
{
    // create default pipeline
    ChannelPipeline pipeline = pipeline(); 

    // traffic shaping handler
    pipeline.addLast("global-traffic-shaping", trafficHandler);

    // SSL support
    if(useSSL)
    {
        SSLEngine sslEngine = createSSLEngine();
        pipeline.addLast("ssl", new SslHandler(sslEngine));
    }

    // memory executor
    pipeline.addLast("memory-executor", execHandler);

    // business logic
    pipeline.addLast("data-processing", 
        new NettyNioClientHandler(
            nettyNioClient, localer, logger, ncMgr, username, useSSL));

    return pipeline;
}

在运行时,我可以通过以下方式设置最大下载速度:

public void setDlSpeedLimit(long limit)
{
    if(limit < 0)
        return;

    trafficHandler.configure(0, limit * 1000L);
}

好的,基本上Netty NIO功能运行良好且快速。当我在应用程序中设置最大下载速度时,我也可以看到带宽使用确实被限制在最大水平。我通过以下方式监视带宽使用:

trafficHandler.getTrafficCounter().getLastReadThroughput();

然而,不幸的是我监测到的最大速度与我之前设置的相差甚远。例如,没有限制时我的下载速度约为2000 kb/s,但当我将限制设置为300 kb/s时,实际下载速度会在700-900 kb/s之间波动。所以,在这种情况下,我的问题是:我可以看到流量整形器正在发挥作用,但并非我希望的那样。我是否错过了什么步骤,例如管道初始化?感谢您的帮助!
2个回答

1

你的 getPipeline() 每次请求新的 pipeline 时都会实例化 GlobalTrafficShapingHandler。你应该只实例化一个并在所有 pipeline 中重复使用它。对于其他类,如 HashedWheelTimer,也是如此。

Netty 有很多必须在 pipeline 之间共享的类。通常文档清楚地说明了这一点。你应该检查每个类的 javadoc,并确保你遵循它们。


当然,你是正确的,在实际代码中我按照你建议的方式进行了操作。GlobalTrafficShapingHandler、HashedWheelTimer和ExecutionHandler在类构造函数之前被创建。如果我的原始帖子让你感到困惑,我很抱歉。我已经相应地进行了更新。 - Matthias

0

好的,看起来没有其他的想法了。
唯一有点帮助我的事情是将计时器增加到5-10秒。

干杯!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接