Запрос через Python.Requests выполняется крайне долго

Я разрабатываю и тестирую (через requests) код удалённого сервера, с какого-то дня я вдруг стал получать ответы с задержкой в 70-80 сек на простейшие запросы. При этом, те же запросы с моего компа через curl, wget или браузер выполняются моментально, как и тот же самый скрипт Питона запускаемый со сторонних серверов.

Я пробовал подключаться и по httpS, и по HTTP (видимо дело не в SSL), локально используя Python 3.7 и 2.7, результат везде один. У меня ОС MacOSX 10.15.1, на сервере стоят Ubuntu 18.04.5, NginX и Aiohttp, но я поднимал hello-world на Flask'e, результат тот же самый, видимо, код сервера тоже не влияет.

Вопрос: почему запрос выполняется ТАК долго, с моего компа на конкретно этот сервер и именно только через Питон?! И как это можно лучше продебажить, чтобы найти причину проблемы?

Я попробовал так, но пользы мало:

import requests
import http.client
import logging

logging.basicConfig(level=logging.DEBUG)
http.client.HTTPConnection.debuglevel = 1
logging.basicConfig()
logging.getLogger().setLevel(logging.DEBUG)
requests_log = logging.getLogger("requests.packages.urllib3")
requests_log.setLevel(logging.DEBUG)
requests_log.propagate = True

# Домен конечно изменён
response = requests.get('http://sub.test.com:5990/')
print('** Code:', response.status_code)
print('** Response:', response.content.decode('utf-8'))

Вывод:

DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): sub.test.com:5990
# Спустя 75 секунд:
send: b'GET / HTTP/1.1\r\nHost: sub.test.com:5990\r\nUser-Agent: python-requests/2.22.0\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: keep-alive\r\n\r\n'
reply: 'HTTP/1.1 200 OK\r\n'
header: Content-Type: text/html; charset=utf-8
header: Content-Length: 13
header: Date: Thu, 03 Sep 2020 19:26:25 GMT
header: Server: Python/3.6 aiohttp/3.6.2
DEBUG:urllib3.connectionpool:http://sub.test.com:5990" GET / HTTP/1.1" 200 13
** Code: 200
** Response: Hello, World!

Если убить скрипт в процессе ожидания, трейсбэк получается такой:

Traceback (most recent call last):
  File "test.py", line 19, in <module>
    response = requests.get(URL)
  File "/Library/Python/3.7/site-packages/requests/api.py", line 75, in get
    return request('get', url, params=params, **kwargs)
  File "/Library/Python/3.7/site-packages/requests/api.py", line 60, in request
    return session.request(method=method, url=url, **kwargs)
  File "/Library/Python/3.7/site-packages/requests/sessions.py", line 533, in request
    resp = self.send(prep, **send_kwargs)
  File "/Library/Python/3.7/site-packages/requests/sessions.py", line 646, in send
    r = adapter.send(request, **kwargs)
  File "/Library/Python/3.7/site-packages/requests/adapters.py", line 449, in send
    timeout=timeout
  File "/Library/Python/3.7/site-packages/urllib3/connectionpool.py", line 672, in urlopen
    chunked=chunked,
  File "/Library/Python/3.7/site-packages/urllib3/connectionpool.py", line 387, in _make_request
    conn.request(method, url, **httplib_request_kw)
  File "/Applications/.../Python3.framework/Versions/3.7/lib/python3.7/http/client.py", line 1229, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "/Applications/.../Python3.framework/Versions/3.7/lib/python3.7/http/client.py", line 1275, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "/Applications/.../Python3.framework/Versions/3.7/lib/python3.7/http/client.py", line 1224, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/Applications/.../Python3.framework/Versions/3.7/lib/python3.7/http/client.py", line 1016, in _send_output
    self.send(msg)
  File "/Applications/.../Python3.framework/Versions/3.7/lib/python3.7/http/client.py", line 956, in send
    self.connect()
  File "/Library/Python/3.7/site-packages/urllib3/connection.py", line 184, in connect
    conn = self._new_conn()
  File "/Library/Python/3.7/site-packages/urllib3/connection.py", line 157, in _new_conn
    (self._dns_host, self.port), self.timeout, **extra_kw
  File "/Library/Python/3.7/site-packages/urllib3/util/connection.py", line 74, in create_connection
    sock.connect(sa)

Update

Было замечено, что указывая IP адрес подключение происходит успешно, видимо, проблема в DNS resolve. Аналог кода из падающего urllib3/util/connection.py выполняется без проблем:

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('sub.test.com', 5990))
sock.close()

Однако выявлено, что в реальном connection.py используется socket.AF_INET6, и с этим аргументом подключение как раз зависает.

Решение

Оказалось, что у домена в DNS есть запись AAAA с недействительным адресом IPv6, помимо A записи с корректным IPv4, и удаление этой записи решило проблему.


Ответы (1 шт):

Автор решения: AivanF.

Оказалось, что у домена в DNS есть AAAA запись с недействительным адресом IPv6, помимо A записи с корректным IPv4. А Python видимо сначала пытается подключиться по IPv6 с таймаутом в 75 сек, в отличие от других программ (curl, wget, браузеры), которые либо имеют короткий таймаут, либо сразу в IPv4 стучатся.

У меня была гипотеза о проблемах с DNS, но большинство прог для его анализа (вроде viewdns.info и dnsdumpster.com) не показывали AAAA записи, поэтому я рано отверг этот вариант.

После моего запроса на исправление DNS записей домена, скрипт стал выполняться с адекватной скоростью.

→ Ссылка