Поиск пропускной способности интернет сервера через Java для потоковой передачи - PullRequest
3 голосов
/ 04 августа 2009

Следуя этой теме. Потоковая передача больших файлов в сервлете Java .

Можно ли найти общую пропускную способность интернета, доступную в текущей машине через Java?

я пытаюсь выполнить потоковую передачу больших файлов через сервлет, основываясь на количестве параллельных запросов и общей ширине полосы, я пытаюсь уменьшить BUFFER_SIZE потока для каждого запроса. имеет смысл?

Есть ли какой-нибудь чистый способ Java? (без JNI)

Ответы [ 5 ]

6 голосов
/ 03 октября 2009

Может быть, вы можете определить, сколько времени приложению нужно отправить один пакет (буфер). И если это больше чем x миллисекунд, тогда уменьшите ваш буфер. Вы можете использовать другие значения для оригинала bufferSize и if (stop - start > 700).

Это основано на теме, которую вы заметили:

ServletOutputStream out = response.getOutputStream();
InputStream in = [ code to get source input stream ];
String mimeType = [ code to get mimetype of data to be served ];
int bufferSize = 1024 * 4;
byte[] bytes = new byte[bufferSize];
int bytesRead;

response.setContentType(mimeType);

while ((bytesRead = in.read(bytes)) != -1) {
    long start = System.currentTimeMillis();
    out.write(bytes, 0, bytesRead);
    long stop = System.currentTimeMillis();
    if (stop - start > 700)
    {
        bufferSize /= 2;
        bytes = new byte[bufferSize];
    }
}

// do the following in a finally block:
in.close();
out.close();
0 голосов
/ 02 октября 2009

РЕДАКТИРОВАТЬ: Перечитывая это, это немного запутано, потому что здесь поздно. По сути, вы не должны делать это с нуля; используйте один из существующих хорошо масштабируемых Java-серверов, поскольку они будут делать это лучше и проще.

Тебе это не понравится, но на самом деле не имеет смысла, и вот почему:

  • Общая пропускная способность не зависит от количества соединений (хотя есть небольшие издержки), поэтому беспорядок с размерами буфера не сильно поможет
  • Ваши куски данных в любом случае разбиваются на пакеты переменного размера. Ваша сетевая карта и протокол будут справляться с этим лучше, чем ваш сервлет
  • Регулярное изменение размера буферов стоит дорого - гораздо лучше повторно использовать постоянные буферы из пула фиксированного размера и иметь все соединения в очереди для прав ввода / вывода
  • Существует полтора миллиарда библиотек, которые помогают с такого рода серверами

Если бы это был я, я бы начал смотреть на мультиплексный ввод / вывод с использованием NIO. Вы почти наверняка найдете библиотеку, которая сделает это за вас. Статья IBM здесь может быть полезной отправной точкой.

Я думаю, что умные деньги дают вам один поток сетевого ввода-вывода и один дисковый поток ввода-вывода с мультиплексированием. Каждое соединение запрашивает буфер из пула, заполняет его данными (из общей сети или диска Stream или Channel), обрабатывает его, а затем возвращает буфер в пул для повторного использования. Никакого изменения размера буферов, просто немного ожидания для каждого куска данных. Если вы хотите, чтобы задержка оставалась короткой, ограничьте количество одновременных активных передач и поставьте в очередь остальные.

0 голосов
/ 30 сентября 2009

Если вы передаете контент через сервлет, то вы можете рассчитать, как быстро работает каждый выходной поток сервлета. Соберите эти данные для всех потоков для пользователя / сеанса, и вы сможете определить, по крайней мере, какова текущая полоса пропускания.

Одним из возможных способов расчета скорости может быть вместо записи больших файлов через поток вывода сервлета , записи в новый FilterOutputStream , который будет отслеживать ваши скорости загрузки.

0 голосов
/ 01 октября 2009

Понятие «общая пропускная способность интернета, доступная на данном компьютере» действительно трудно определить. Однако настройка размера локального буфера не повлияет на объем данных, передаваемых отдельному клиенту.

Скорость, с которой данный клиент может получать данные с вашего сервера, зависит от клиента и от времени. Для любого данного соединения вы можете быть ограничены локальным восходящим соединением с Интернетом (например, сервером в DSL), или вы можете быть ограничены где-то в ядре (маловероятно) или на удаленном конце (например, сервер в центре обработки данных, клиент по телефонной линии). Когда у вас много соединений, каждое отдельное соединение может иметь разные узкие места. Измерение этой доступной полосы пропускания является сложной проблемой; см., например, этот список исследований и инструментов по теме.

В целом, TCP будет обрабатывать использование всей доступной пропускной способности справедливо для любого данного соединения (хотя иногда он может реагировать на изменения доступной пропускной способности медленнее, чем вам нравится). Если клиент не может обработать больше данных, вызов записи блокируется.

Вам нужно только настроить размер буфера в связанном вопросе, если вы обнаружите, что видите низкую пропускную способность и причина этого - недостаточно буферизованных данных для записи в сеть. Другая причина, по которой вы можете настроить размер буфера, - это если у вас так много активных соединений, что у вас мало памяти.

В любом случае реальный ответ может состоять в том, чтобы вообще не буферизовать, а вместо этого поместить ваши статические файлы на отдельный сервер и использовать что-то вроде thttpd для их обслуживания (используя системный вызов, такой как sendfile ) вместо сервлета. Это помогает гарантировать, что узкое место находится не на вашем сервере, а где-то в Интернете, вне вашего контроля.

0 голосов
/ 04 августа 2009

Единственный способ найти доступную полосу пропускания - это контролировать / измерять ее. В Windows у вас есть доступ к Net.exe и вы можете получить пропускную способность каждого сетевого адаптера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...