Java UrlConnection вызывает исключения «Сброс соединения» при высокой нагрузке.Зачем? - PullRequest
6 голосов
/ 02 февраля 2012

Я использую Java для потоковой передачи файлов из Amazon S3 на 64-разрядных серверах Linux (Ubuntu 10).

Я использую отдельный поток для каждого файла, и каждый файл открывает HttpURLConnection который загружает и обрабатывает каждый файл одновременно.

Все работает прекрасно, пока я не достигну определенного количества потоков (обычно около 2-300 одновременных потоков).В нерегулярные моменты после этого несколько (скажем, 10) потоков начнут испытывать java.net.IOException: Connection reset ошибок одновременно .

Я ограничиваю скорость загрузки, и я намного ниже 250 Мбит / с.предел экземпляра m1.large.Существует также незначительная нагрузка на все остальные аспекты сервера (например, процессор, средняя загрузка и использование памяти все в порядке).

Что может быть причиной этого или как я могу отследить это?

Ответы [ 5 ]

4 голосов
/ 09 февраля 2012

Нетривиально угадать, что может случиться, но это пара советов, может быть, некоторые из них применимы к вашему контексту:

  • можете ли вы проверить свою оболочку (linux bash / zsh или любой другой)чтобы увидеть, поднимаете ли вы стандартные ограничения, ограничивающие количество файловых дескрипторов (но также и сокетов), воспользуйтесь bash shell
  • Вы явно закрывали потоки в своем коде Java?не закрытие потоков может привести к таким умным проблемам
  • попробуйте настроить ядро ​​TCP для Linux на Google, чтобы проверить, имеет ли ваш сервер Ubuntu подходящий стек для такого контекста загрузки ...

HTH Джером

2 голосов
/ 10 февраля 2012

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

0 голосов
/ 13 февраля 2012

Возможно, у вас заканчивается эфемерный порт .Это происходит под нагрузкой, когда многие недолговечные соединения быстро открываются и закрываются.Стандартная Java HttpURLConnection не даст вам гибкости, необходимой для установки правильных опций сокетов.Я рекомендую перейти к проекту Apache HttpComponents и настроить параметры следующим образом ...

...
HttpGet httpGet = new HttpGet(uri);
HttpParams params = new BasicHttpParams();
params.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 16 * 1000); // 16 seconds
params.setParameter(CoreConnectionPNames.SO_REUSEADDR, true); // <-- teh MOJO!

DefaultHttpClient httpClient = new DefaultHttpClient(connectionManager, params);
BasicHttpContext httpContext = new BasicHttpContext();
HttpResponse httpResponse = httpClient.execute(httpGet, httpContext);

StatusLine statusLine = httpResponse.getStatusLine();
if (statusLine.getStatusCode() >= HTTP_STATUS_CODE_300)
{
...

Я пропустил некоторый код, например, настройку connectionManager, но вы можете получить его изих документы.

[Обновление] Вы также можете добавить params.setParameter(CoreConnectionPNames.SO_LINGER, 1);, чтобы эфемерные порты не задерживались до восстановления.

0 голосов
/ 13 февраля 2012

Одной из наиболее распространенных причин подобных проблем является то, что промежуточный прокси-сервер (брандмауэр, балансировщик нагрузки) отбрасывает то, что он считает неактивным (или слишком долгоживущим) HTTP-соединением. Но помимо этой общей возможности, EC2 определенно имеет больше перегибов, как и другие.

0 голосов
/ 06 февраля 2012

Проблема здесь в основном на вашем языке.Высокая нагрузка вызывает состояние ошибки, а условие ошибки приводит к исключению.Не наоборот.

...