Netty Adaptive UDP Multicast Поддержка

Новички, испытывающие затруднения при обработке видеопотока UDP с использованием Netty 3.2.4. На разных машинах мы видим сброшенные байты и т.д., используя Netty. У нас есть небольшой счетчик после того, как Нетти получает байты, чтобы увидеть, сколько байтов получено. Разница больше, чем то, что объясняется ненадежностью UDP. В нашем случае мы также сохраняем байты в файл для воспроизведения видео. Воспроизведение видео в VLC действительно иллюстрирует пропущенные байты. (Размеры отправляемых пакетов составляли около 1000 байт).

Вопросы

  • Верны ли наши предположения об Netty API с точки зрения невозможности использования AdaptiveReceiveBufferSizePredictor для прослушивателя потока UDP?
  • Есть ли лучшее объяснение поведения, которое мы наблюдаем?
  • Есть ли лучшее решение? Есть ли способ использовать адаптивный предиктор с UDP?

Что мы попробовали

...
DatagramChannelFactory datagramChannelFactory = new OioDatagramChannelFactory(
                                                Executors.newCachedThreadPool());
connectionlessBootstrap = new ConnectionlessBootstrap(datagramChannelFactory);
...
datagramChannel = (DatagramChannel) connectionlessBootstrap.bind(new 
                  InetSocketAddress(multicastPort));
datagramChannel.getConfig().setReceiveBufferSizePredictor(new   
                FixedReceiveBufferSizePredictor(2*1024*1024));
...
  • Я думаю, что из документации и поисков в Google правильный способ сделать это - использовать OioDatagramChannelFactory вместо NioDatagramChannelFactory.

  • Кроме того, хотя я не смог найти объяснения, изложенного выше, вы можете использовать только FixedReceiveBufferSizePredictor с OioDatagramChannelFactory (против AdaptiveReceiveBufferSizePredictor). Мы выяснили это, взглянув на исходный код и осознав, что метод предыдущего ReceiveBufferSize() AdaptiveReceiveBufferSizePredictor не вызывался из класса OioDatagramWorker (тогда как он вызывался из NioDatagramWorker)

  • Итак, мы изначально установили FixedReceivedBufferSizePredictor в (2*1024*1024)

Наблюдаемое поведение

  • Работая на разных машинах (с разной вычислительной мощностью), мы видим, что Netty принимает разное количество байтов. В нашем случае мы транслируем видео через UDP и можем использовать воспроизведение потоковых байтов для диагностики качества считываемых байтов (размеры отправляемых пакетов составляли около 1000 байтов).

  • Затем мы экспериментировали с различными размерами буфера и обнаружили, что 1024 * 1024, кажется, заставляет все работать лучше... но на самом деле понятия не имеет, почему.

  • Рассматривая, как работает FixedReceivedBufferSizePredictor, мы поняли, что он просто создает новый буфер каждый раз, когда приходит пакет. В нашем случае это создаст новый буфер размером 2 * 1024 * 1024 байта, независимо от того, был ли пакет 1000 байтов или 3 МБ. Наши пакеты были только 1000 байтов, поэтому мы не думали, что это наша проблема. Может ли какая-либо из этих логик вызывать проблемы с производительностью? Например, создание буфера каждый раз, когда приходит пакет?

Наш обходной путь

Затем мы подумали о том, как сделать размер буфера динамическим, но поняли, что не можем использовать AdaptiveReceiveBufferSizePredictor, как отмечалось выше. Мы экспериментировали и создали наш собственный MyAdaptiveReceiveBufferSizePredictor вместе с сопровождающими классами MyOioDatagramChannelFactory, *Channel, *ChannelFactory, *PipelineSink, *Worker (которые в конечном итоге вызывают MyAdaptiveReceiveBufferSizePredictor). Предиктор просто изменяет размер буфера, чтобы удвоить размер буфера в зависимости от размера последнего пакета или уменьшить его. Это, казалось, улучшило вещи.

1 ответ

Не верно уверен, что вызывает ваши проблемы с производительностью, но я нашел эту тему.
Это может быть вызвано созданием ChannelBuffers для каждого входящего пакета, и в этом случае вам придется ждать Milestone 4.0.0.

Другие вопросы по тегам