Как правильно ограничить использование полосы пропускания с помощью Java netty?

Для клиента загрузки, который я разработал на Java, используя netty nio lib, я также реализовал функцию ограничения полосы пропускания. Технически я делаю это через объект 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;
}

И во время выполнения я установил max. скорость загрузки через

public void setDlSpeedLimit(long limit)
{
 if(limit < 0)
 return;
 trafficHandler.configure(0, limit * 1000L);
}

Итак, в основном функциональность netty nio работает отлично и быстро. Когда я устанавливаю max. скорость загрузки в приложении, я также вижу, что использование полосы пропускания действительно ограничено макс. уровень. Я отслеживаю использование полосы пропускания через

trafficHandler.getTrafficCounter().getLastReadThroughput();

Однако, к сожалению, макс. скорость, которую я контролирую, - это не то, что я задал раньше, даже не закрываю. Например, я изначально (без ограничения) имел скорость загрузки около 2000 кбит/с, тогда я установил предел до 300 кбит/с, как описано выше, но реальная скорость загрузки варьируется от 700-900 кбит/с.

Итак, моя проблема в этом случае: я вижу, что создатель трафика что-то делает, но не так, как я этого хотел. Я что-то пропустил здесь, любой шаг в инициализации конвейера, например?

Заранее благодарим за помощь!

2 ответа

Хорошо, так что, похоже, нет других идей. Единственное, что помогло мне немного, - увеличить счетчик времени до 5-10 секунд.

Ура!


Ваш getPipeline() создает экземпляр GlobalTrafficShapingHandler каждый раз, когда запрашивается новый конвейер. Вы должны только создать экземпляр одного и повторно использовать его во всех конвейерах. Это справедливо и для других классов, таких как HashedWheelTimer.

Netty имеет довольно много классов, которые должны быть разделены между конвейерами. Обычно в документации четко указано это. Вы должны изучить javadoc каждого класса и убедиться, что вы следите за ними.

licensed under cc by-sa 3.0 with attribution.