В определенный момент времени, от пользователя одной межрегиональной компании было получено обращение о довольно таки необычной и впервые мною наблюдаемой ошибке. В заявке отмечалось, что время от времени у клиента зависает копирование файлов по сети. Постепенно проблема эскалировалась на некоторое ограниченное количество других станции, при этом не приобретя характер эпидемии. По началу, описанная ситуация была зафиксирована в корпоративной сети между клиентскими рабочими станциями, функционирующими под управлением операционной системы Windows 7 и файловым сервером на Windows 2008R2. Зависание копирования файлов наблюдалось только для файлов, имеющих определенный размер, ориентировочно в диапазоне от 100 мегабайт и более, и визуально характеризовалось останавливающимся на произвольной отметке индикатором прогресса копирования и оценочной скоростью 0 байт/сек.:
..в таком вот состоянии процесс копирования мог пребывать сколь угодно долго, абсолютно не реагируя ни на какие действия пользователя применительно к окну.
Проблема
Поначалу создалось впечатление, что в проблеме однозначно участвует файловый сервер Windows 2008R2, однако чуть позже, после более детального изучения инцидента стало очевидным, что зависает копирование файлов так же и между двумя произвольными клиентскими рабочими станциями, включенными в корпоративную локальную сеть. И в то же время, инцидент проявлял себя не часто и далеко не на всех машинах, было зафиксировано, что некоторые станции в корпоративной сети работали с тем же файловым сервером и между собой абсолютно нормально. При проявлении описанной проблемы сама система функционировала в штатном режиме, однако процесс explorer.exe, в контексте которого происходило копирование, зависал наглухо, зачастую не давая себя снимать через диспетчер задач. При этом, как минимум, протокол SMB
переставал нормально функционировать, наблюдались проблемы с доступам к сетевым ресурсам. К тому же, в процессе выключения проблемной станции, этап завершения сеанса мог выполняться бесконечно долго. На основании обобщенного анализа всех деталей инцидента, можно было сделать вывод о достаточно сыром коде обработки различных нештатных ситуаций в стеке TCP/IP Windows 7, однако истинная причина крылась вовсе не в этом.
Как всегда, по началу применялся всеми горячо любимый, великий и могучий "метод тыка", обновлялись драйвера, сбрасывались настройки сетевого интерфейса, сравнивались установленные обновления, устраивались различные ритуальные танцы с бубном вокруг проблемных машин :), использовались и прочие, не менее действенные методы из арсенала технического специалиста. В итоге всего этого увлекательного действа виновник был найден, и им оказался сетевой маршрутизатор (располагающийся на пути следования пакетов данных), имеющий одну интересную особенность: прошивка не поддерживала динамическое окно передачи.
Теория
Перед нами встает резонный вопрос, что же это за динамическое окно передачи и какое влияние данная технология оказывает на процесс передачи файлов между хостами в сети? Применительно к протоколу TCP/IP определены такие понятия как окно приема TCP (TCP Receive Window, RWIN) и окно передачи TCP (TCP Send Window). В действительности это одно логическое окно, просто создается оно как на принимающей, так и на передающей сторонах при инициализации TCP соединения между двумя узлами сети, имеет на обеих сторонах одинаковую размерность, представляет из себя, фактически, типичный буфер (блок данных в памяти). Окно используется для контроля скорости потока принимающей стороной, а так же для указания количества данных, которые могут быть отправлены отправителем за один прием, оно так же определяет, какой объем неподтвержденных данных может находиться в пути от отправителя к получателю. Отправитель может посылать только байты передаваемого потока, находящиеся в данный момент внутри этого логического окна. Окно как бы перемещается по исходящему байтовому потоку данных на отправляющей стороне и входящему байтовому потоку данных на принимающей стороне. Выражаясь яснее, участок данных в исходящем байтовом потоке, который отправителю разрешено отправлять, соответствует участку данных во входящем байтовом потоке, который получатель может принять.
Технология масштабирования окна TCP (TCP Window Scaling), описанная в предложении RFC 1323, была реализована разработчиками впервые еще в сетевом стеке TCP/IP операционной системы Windows 2000, но по-умолчанию предусмотрительно была отключена. В версиях Windows, предшествующих Vista, окно приема TCP имело максимальный размер, равный 64 килобайта (65535 байт). Начиная с Windows Vista разработчики модифицировали стек TCP/IP и реализовали алгоритм автоматической настройки окна приема TCP (TCP Receive Window Auto-Tuning), который использует TCP Window Scaling Option. Теперь уже окно приема TCP, за счет введения дополнительной опции в заголовке TCP пакета, может расширяться аж до 16 мегабайт. Алгоритм TCP Receive Window Auto-Tuning позволяет ядру определять оптимальный размер окна приема TCP на основании измерения интегрального показателя задержки передачи и скорости извлечения данных принимающим приложением, после чего размер окна адаптируется (в реальном времени) в соответствии с изменяющимися параметрами физического канала передачи и приложения. Во время передачи данных в рамках TCP-сессии обе стороны стараются установить оптимальный размер данного окна для повышения производительности обмена данными через каналы с высокой пропускной способностью и высоким показателем задержки передачи, к коим и относится большинство современных каналов сети Интернет.
Ан нет, огромное количество сетевых маршрутизаторов, фаерволов и прочих "продвинутых" устройств этого делать не умеют, а некоторые уже никогда и не научатся по причине того, что производители не выпускают к ним новые версии прошивок.
Решение
Для решения проблемы зависания копирования файлов по сети к нам на выручку приходит системная утилита командной строки netsh
, предназначенная для управления параметрами сетевой конфигурации локальной или удаленной станции.
Давайте посмотрим текущее состояние некоторых параметров настройки интерфейса TCP/IP, выполнив следующую команду:
netsh interface tcp show global
В ответ мы получили вывод текущих параметров настройки TCP/IP, среди которых нас интересует "Уровень автонастройки окна получения", который по-умолчанию имеет значение "normal":
Параметр может принимать следующие значения:
- disabled предписывает использовать фиксированное значение окна приема TCP. Значение по-умолчанию = 64 килобайта (65535 байт). Полная совместимость со устаревшим сетевым оборудованием;
- highlyrestricted позволяет окну приема TCP выходить за границы значения по-умолчанию, в разумных пределах;
- restricted позволяет окну приема TCP выходить за границы значения по-умолчанию, еще более свободно;
- normal установка по умолчанию. Допускает увеличение окна приема TCP с учетом большинства возможных сценариев обмена;
- experimental позволяет окну приема TCP увеличиваться до максимальных значений (16+ мегабайт). Не рекомендуется, потому как может вызвать падение производительности в большинстве возможных сценариев обмена;
Для начала переводим уровень автонастройки окна получения в значение disabled, фактически отключая автонастройку и предписывая использование фиксированного значения:
netsh interface tcp set global autotuninglevel=disabled
Вышеприведенная команда полностью устраняет зависание копирования файлов, однако, опционально, я бы рекомендовал выполнить еще и следующую.
Следующая команда отключает масштабирование на принимающей стороне (receive-side scaling), которое распределяет сетевую нагрузку между несколькими ядрами процессора в многопроцессорной системе:
netsh interface tcp set global rss=disabled
Выводы
В ситуации, когда обмен данными происходит между двумя, напрямую подключенными друг к другу, станциями под управлением операционных систем Windows версий Vista и более поздних, проблема никогда себя не обнаруживает. Однако в современной корпоративной сетевой среде довольно часто применяются управляемые коммутаторы и прочие сложные сетевые устройства, и вот именно их собратья с устаревшим микропрограммным обеспечением, не поддерживающие динамическое окно передачи, и становятся источником проблемы зависания копирования файлов (и ряда смежных). Конкретно в нашем случае виновником был Cisco Catalyst 3750 v2 с версией Cisco IOS Software младше 12.3(15). В дополнение к данной конфигурации, теоретически ошибка может проявляться при передаче между двумя станциями, подключенными напрямую, одна из которых работает под управлением Windows версии Vista и более поздних, а другая под управлением старых операционных систем (таких как Windows XP и более ранних), однако я лично подобную связку не тестировал.
спасибо - полезно
Прекрасная грамотная и вдумчивая статья, позволяющая (по аналогии,если с умом подойти) понять львиную долю неисправностей в среде Windows.
Остается только воскликнуть: " Автора!"
В общем глубокий респект и уважение.
спасибо. действительно, у Windows огромное количество замаскированных недоработок... и периодически они "выстреливают" :) ну что поделать, надо как то дальше жить..
Впрочем, желаю автору сохранения его скромности и не слишком витиеватого стиля.
Это намного важнее всех писаний.
Большое спасибо за статью! Помогла решить эту проблему. Я не особо разбираюсь в глубинах. Как раньше называли таких как я "эникейщик". Реально работа встала из-за нехватки места, а сбросить на nas не могу, виснет :(
Понимаю, что дело не в оборудовании так как неделю назад все работало. Пробно залил на nas большой файл с ноутбука - все ок, значит понял, что комп виноват. Применил ваши настройки - все ок.
Еще раз спасибо за ваше решение!
не за что, заходите :)
Спасибо! К такому невозможно прийти
ах*енно, теперь вообще не грузит
подробности?
Аналогичные симптомы. Только у меня локальная сеть с altlinux 8 и mac os x 10.7.5. Компьютеры соединены проводами через рутер keenetic. Копирую папку с фото и видео из mac os на диск в altlinux. Начинает резво, но на каких-то файлах замерзает и всё. В папке есть несколько больших (100, 200, ...1000...mb) файлов с видео. Отдельные файлы любого объема копирует нормально. Интересно, что при попытке очередной раз скопировать туже папку в тоже место, с указанием не перезаписывать уже имеющиеся файлы замерзает сразу. Поведение одинаково как с smb так и с afp. Возможно это не ваш случай. Что делать не пойму. Может здесь подскажут?
keenetic на свежей прошивке? тогда надо смотреть в сторону протоколов. может сетевой стек где-нибудь тюнинговался при помощи sysctl? сетевые анализаторы пробовали типа tcptrace и подобные?
Спасибо.
Keenetic свежий и прошивка в нем последняя.
Попробую покапать по вашим наводкам.
Не нашел...
У меня винда 10, оперативы 32...
Висит, собака. Мертво висит(
Спасибо огромное! Больше года мучался с этой проблемой, только сегодня нашел эту статью! Наконец-то заработало копирование по сети!
советую прошивку у роутера/маршрутизатора/коммутатора обновить заодно, если доступен.
Огромное Спасибо!
Данная статья помогла устранить проблему зависания при копировании.
Но Через неделю ситуация повторилась.
ЧЯДНТ?
Куда копать дальше?
Может быть подобную настройку надо произвести и на роутере (Mikrotik hAP ac^2 , RouterOS v6.47.1 (stable)).
Но возможно ли это?
При этом заметил разницу:
При копировании файла (56Гиг) с использованием \\tsclient\...., т.е. с сервера на станцию - Виснит на 8-10процентах. Скорость при этом не более 29мб.
При копировании с Сетевого ресурса на станцию этого же файла (скорость до 100Мб) и зависания нет.
Что это?
что за ОС на серверах и клиенте?
При этом копирование аналогичного файла с другого сервера на эту же станцию (уже через интернет ) проходит успешно.
Отличная статья ;) Доступно и внятно написано.
Возможно немного не по теме, но мало ли -2 сервера на 2019й винде, копирование через свитч по 10Gbit между 2мя серверами волнообразное с выраженной периодичностью. Может, кто сталкивался и смог победить? :)
скрины дадите поглядеть?