Назад | Перейти на главную страницу

Отслеживание ошибок «сброса подключения» в Linux

Я обрабатываю большое количество одновременных загрузок (около 500 на сервер) с использованием Java.

Все файлы загружаются с Amazon S3, а сервер загрузки - это экземпляр EC2 m1.large.

Иногда 2 или более потоков будут одновременно быть нарушенным, что приведет к исключению java.net.SocketException. Иногда может быть одновременно прервано до 10 потоков.

У меня одинаковые результаты при загрузке с серверов Amazon S3 и Akamai. Это происходит только тогда, когда нагрузка начинает быть достаточно высокой (200 и более одновременных загрузок).

У меня нормальный процессор, нагрузка на сеть и память.

Я сильно подозреваю, что проблема на моем сервере, а не на S3 и Akamai. Как я мог отладить это и найти причину?

Вы можете захватить трафик с помощью tcpdump и посмотрите на это после разрыва связи. Например, в Wireshark есть опция «следовать TCP-потоку», которая позволяет легко изолировать сломанный, как только вы найдете последний пакет.

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

Для начала вы можете взглянуть на ошибки, сообщаемые сетевым интерфейсом (через ifconfig) и посмотрите, увеличивается ли это число значительно при разрыве соединений.

Есть ли брандмауэр / NAT на пути между вами и S3?

Не могли бы вы одновременно захватить (tcpdump -w file -s 0) трафик в 2-х точках - между вашим сервером и межсетевым экраном, и между межсетевым экраном и S3, потом сравнивать дампы? Перед запуском tcpdump убедитесь, что часы точно синхронизированы с использованием NTP на захватывающих хостах.

Затем сравните оба сетевых захвата в тот момент, когда соединение было разорвано.

У меня была похожая неуловимая проблема, и, сравнивая дампы сетевого трафика, я обнаружил, что это было связано с тем, что SACK был активен на моем сервере Linux, но неправильно интерпретировался межсетевым экраном Cisco ASA, который обрабатывал трафик, идущий из Интернета.

Пришлось отключить SACK с помощью sysctl (net.ipv4.tcp_sack).