Обновление ниже:
У меня возникла аналогичная проблема с несвязанным скриптом на виртуальной машине Debian в другом центре обработки данных.
Это подозрительно похоже на описанную проблему Вот (и, как и человек, задающий этот вопрос, у меня нет прокси-сервера, настроенного перед сервером).
Основное отличие от приведенного ниже описания заключается в том, что когда я подключаюсь к зависшему процессу, я вижу вызов recvfrom
скорее, чем read
:
$ strace -p 17527
Process 17527 attached - interrupt to quit
recvfrom(3,
Однако у Python нет никакого впечатления, что он проксируется:
>>> import os; print os.getenv("HTTP_PROXY"), os.getenv("http_proxy")
None, None
Так что я все еще в тупике. К сожалению, на связанный вопрос также нет окончательного ответа.
(Мне также интересно, если этот вопрос связано, но кажется маловероятным, что S3 не соблюдает Connection: close
заголовки.)
У меня есть несколько серверов Debian (Wheezy, x86_64), каждый из которых демонстрирует следующее поведение:
На всех серверах есть набор заданий cron, которые, помимо прочего, извлекают данные из S3. Обычно они работают нормально, но иногда ps aux
показывает, что некоторые из заданий, начатых несколько часов или дней назад, все еще выполняются и не завершены должным образом.
Осматривая их с strace -p <pid>
показывает, что во всех случаях процесс зависает от команды чтения. Например, результат процесса, который я только что проверил, был:
$ strace -p 12089
Process 12089 attached - interrupt to quit
read(5,
И проверка дескрипторов открытых файлов дает мне следующее:
$ sudo lsof -i | grep 12089
python 12089 user 5u IPv4 809917771 0t0 TCP my.server.net:35427->185-201.amazon.com:https (ESTABLISHED)
Сначала я предположил, что это произошло из-за того, что в сценариях Python не задан тайм-аут чтения, но этого не произошло по нескольким причинам:
socket.setdefaulttimeout
- это в Python 2.7, но кодовая база должна быть совместима с 2.5) зависло со вчерашнего дня.svn up --non-interactive
процесс (с использованием subprocess.Popen
, чего это стоит).Ситуация с этим процессом SVN аналогична -
Python ждет SVN:
$ strace -p 28034
Process 28034 attached - interrupt to quit
wait4(28127,
И SVN ждет read
звонок для завершения:
$ strace -p 28127
Process 28127 attached - interrupt to quit
read(6,
И это чтение указывает на другой внешний хост:
$ sudo lsof -i | grep 28127
svn 28127 user 3u IPv4 701186417 0t0 TCP my.server.net:49299->sparrow.telecommunity.com:svn (ESTABLISHED)
svn 28127 user 6u IPv4 701186439 0t0 TCP my.server.net:49309->sparrow.telecommunity.com:svn (ESTABLISHED)
(Похоже, svn:externals
свойство установлено на ez_setup svn://svn.eby-sarna.com/svnroot/ez_setup
об обновляемом каталоге; судя по их веб-сайту, я думаю, что это перенаправление на teleity.com)
Дополнительные, возможно, важные моменты:
svn:externals
являются; это было создано до меня.ifconfig
). Я предполагаю, что это указывает на проблему с конфигурацией сети, но я не уверен, с чего начать.Итак, я предполагаю, что мои вопросы:
read
звонки, которые мне нужно знать, чтобы избежать бесконечного зависания процессов?Могу ли я исправить это на системном уровне, или что-то не так с каждым отдельным процессом?
Сложно сказать, потому что неизвестно, что происходит на уровне протокола. В основном read(2)
заблокирует на неопределенный срок при условии: -
Теперь может быть, что что-то не так с процессом, например, другой конец ожидает ответа от вас, прежде чем отправлять дополнительные данные, или предыдущий ответ с другого конца ожидает, что SVN что-то сделает. еще перед запросом дополнительных данных. Предположим, например, что пришел ответ об ошибке, который должен заставить клиента повторно отправить некоторую информацию.
Вы не можете исправить это изящно, потому что по имеющейся у вас информации невозможно определить, что отправитель этих данных ожидает от вас. Однако есть несколько возможных способов избежать проблемы и сообщить о ней.
wait
в простом режиме блокировки запустите wait
и настроить тревогу в родительском процессе. Теперь, когда процесс не может быть завершен в течение определенного периода времени, вы можете убить его и сообщить об этом. Дешевый способ сделать это - изменить subprocess.Popen для вызова timeout
команда.socket
системный вызов, чтобы также добавить тайм-аут для получателя. И то, и другое нетривиально. Это может вызвать svn
вести себя неожиданным образом.Есть ли что-то принципиально иное в том, как OS X и Linux обрабатывают вызовы чтения, что мне нужно знать, чтобы избежать бесконечного зависания процессов?
Я не знаю ответа на этот вопрос, однако, если оба ведут себя положительно правильно, они оба должны вести себя одинаково. Если вы пытаетесь читать из сокета, который еще не подготовлен для отправки вам данных, поток блокируется на неопределенный срок, что является ожидаемым поведением.
В целом, я думаю, что ваш лучший выбор атаки - ожидать вашего svn
команда должна быть завершена в течение определенного периода времени. Если он не убьет его, сообщите об этом.
Я думаю, что выяснил проблему (ы), описанную выше, и большая часть загадки проистекает из моего неправильного понимания того, что происходило на серверах.
Были следующие основные проблемы:
Я оставляю этот ответ здесь, чтобы объяснить, что происходит, но я собираюсь принять ответ Мэтью, потому что он был прав в отношении фактических возможных проблем.