Подтвердить что ты не робот

Как я могу отладить то, что вызывает отказ в соединении или время подключения?

У меня есть следующий код, который работал около года:

import urllib2

req = urllib2.Request('https://somewhere.com','<Request></Request>')
data = urllib2.urlopen(req)
print data.read()

В последнее время произошли некоторые случайные ошибки:

  • urllib2.URLError: <urlopen error [Errno 111] Connection refused>
  • <urlopen error [Errno 110] Connection timed out>

След неудачи:

Traceback (most recent call last):
  File "test.py", line 4, in <module>
    data = urllib2.urlopen(req).read()
  File "/usr/lib/python2.7/urllib2.py", line 126, in urlopen
    return _opener.open(url, data, timeout)
  File "/usr/lib/python2.7/urllib2.py", line 400, in open
    response = self._open(req, data)
  File "/usr/lib/python2.7/urllib2.py", line 418, in _open
    '_open', req)
  File "/usr/lib/python2.7/urllib2.py", line 378, in _call_chain
    result = func(*args)
  File "/usr/lib/python2.7/urllib2.py", line 1215, in https_open
    return self.do_open(httplib.HTTPSConnection, req)
  File "/usr/lib/python2.7/urllib2.py", line 1177, in do_open
    raise URLError(err)
urllib2.URLError: <urlopen error [Errno 111] Connection refused>

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

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

С telnet

Я просто тестировал с помощью telnet, иногда это удается, иногда это не так, как мой Python.

Успех:

$ telnet somewhere.com 443
Trying XXX.YY.ZZZ.WWW...
Connected to somewhere.com.
Escape character is '^]'.
Connection closed by foreign host.

При отказе подключения:

$ telnet somewhere.com 443
Trying XXX.YY.ZZZ.WWW...
telnet: Unable to connect to remote host: Connection refused

Время ожидания:

$ telnet somewhere.com 443
Trying XXX.YY.ZZZ.WWW...
telnet: Unable to connect to remote host: Connection timed out
4b9b3361

Ответ 1

Проблема

Проблема заключается в сетевом уровне. Ниже приведены коды состояния:

  • Connection refused: коллега не прослушивает соответствующий сетевой порт, к которому вы пытаетесь подключиться. Обычно это означает, что либо брандмауэр активно отказывает в соединении, либо соответствующая служба не запускается на другом сайте или перегружается.

  • Connection timed out: во время попытки установить TCP-соединение никакой ответ не поступал с другой стороны в течение заданного срока. В контексте urllib это также может означать, что ответ HTTP не пришел вовремя. Иногда это также вызвано брандмауэрами, иногда перегрузкой сети или большой нагрузкой на удаленный (или даже локальный) сайт.

В контексте

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

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

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

Отладка этого

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

Чтобы исключить перегрузку сети как проблему, вы можете использовать инструмент, например mtr или traceroute или даже ping, чтобы узнать, потеряны ли пакеты удаленному сайту. Обратите внимание, что если вы видите потерю в mtr (и любой инструмент traceroute, если на то пошло), вы всегда должны учитывать первый хост, где происходит потеря (в пути от вашего к удаленному) в качестве пакетов сбрасывания, из-за способа ICMP. Если пакеты теряются только при последнем прыжке в течение длительного времени (скажем, 100 пакетов), у этого узла определенно есть проблема. Если вы видите, что это поведение является постоянным (в течение нескольких дней), вы можете обратиться к администратору.

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

Если перегрузка сети не является проблемой (т.е. не более, скажем, 5% пакетов теряется), вы должны связаться с администратором удаленного сервера, чтобы выяснить, что не так. Он может видеть соответствующую информацию в системных журналах. Запуск анализатора пакетов на удаленном сайте также может быть более показательным, чем на локальном сайте. Проверяется, открыт ли порт с помощью netstat -tlp.

Ответ 2

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

Тайм-ауты или отклоненные соединения могут означать, что удаленный хост слишком занят.