Python HTTP ПОЛУЧАЕТ исключение raise через 300 секунд из контейнера Docker

#python #docker #curl #python-requests #pycurl

#python #docker #curl #python-запросы #pycurl

Вопрос:

Я пытаюсь ПОЛУЧИТЬ данные из внешней службы, используя Python, из контейнера Docker. Мне нужно достичь двух разных конечных точек, скажем:

 endpointA = "https://myhost:1234/resA" # Requests take about 1 minute to complete
endpointB = "https://myhost:1234/resB" # Requests take about 8 minutes to complete
  

Я пытался использовать две разные библиотеки, запросы:

 import requests
headers = {'Authorization': 'Basic XXXXXXXXXXXXXXXXXXXXXX', 'Content-Type': 'application/json'}
response = requests.get(endpointA, verify=False, headers=headers)
  

и Pycurl:

 import pycurl

headers = ['Authorization: Basic XXXXXXXXXXXXXXXXXXXXXX', 'Content-Type: application/json']

buffer = BytesIO()
c = pycurl.Curl()
c.setopt(c.VERBOSE, True)
c.setopt(c.URL, endpointA)
c.setopt(c.WRITEDATA, buffer)
c.setopt(c.SSL_VERIFYPEER, False)
c.setopt(c.SSL_VERIFYHOST, False)
c.setopt(c.HTTPHEADER, headers)
c.perform()
c.close()
  

Мой код выполняется без проблем с локального (возвращаются как endpointA, так и endpointB).

При запуске внутри контейнера Docker запросы к endpointA работают, но запрос к endpointB вызывает исключения через 300 секунд:

в случае запросов:

 Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/urllib3/connectionpool.py", line 670, in urlopen
    httplib_response = self._make_request(
  File "/usr/local/lib/python3.8/site-packages/urllib3/connectionpool.py", line 426, in _make_request
    six.raise_from(e, None)
  File "<string>", line 3, in raise_from
  File "/usr/local/lib/python3.8/site-packages/urllib3/connectionpool.py", line 421, in _make_request
    httplib_response = conn.getresponse()
  File "/usr/local/lib/python3.8/http/client.py", line 1347, in getresponse
    response.begin()
  File "/usr/local/lib/python3.8/http/client.py", line 307, in begin
    version, status, reason = self._read_status()
  File "/usr/local/lib/python3.8/http/client.py", line 276, in _read_status
    raise RemoteDisconnected("Remote end closed connection without"
http.client.RemoteDisconnected: Remote end closed connection without response

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/requests/adapters.py", line 439, in send
    resp = conn.urlopen(
  File "/usr/local/lib/python3.8/site-packages/urllib3/connectionpool.py", line 726, in urlopen
    retries = retries.increment(
  File "/usr/local/lib/python3.8/site-packages/urllib3/util/retry.py", line 403, in increment
    raise six.reraise(type(error), error, _stacktrace)
  File "/usr/local/lib/python3.8/site-packages/urllib3/packages/six.py", line 734, in reraise
    raise value.with_traceback(tb)
  File "/usr/local/lib/python3.8/site-packages/urllib3/connectionpool.py", line 670, in urlopen
    httplib_response = self._make_request(
  File "/usr/local/lib/python3.8/site-packages/urllib3/connectionpool.py", line 426, in _make_request
    six.raise_from(e, None)
  File "<string>", line 3, in raise_from
  File "/usr/local/lib/python3.8/site-packages/urllib3/connectionpool.py", line 421, in _make_request
    httplib_response = conn.getresponse()
  File "/usr/local/lib/python3.8/http/client.py", line 1347, in getresponse
    response.begin()
  File "/usr/local/lib/python3.8/http/client.py", line 307, in begin
    version, status, reason = self._read_status()
  File "/usr/local/lib/python3.8/http/client.py", line 276, in _read_status
    raise RemoteDisconnected("Remote end closed connection without"
urllib3.exceptions.ProtocolError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))

  

в случае pycurl:

 Traceback (most recent call last):
  File "test.py", line 230, in get_data
    c.perform()
pycurl.error: (52, 'Empty reply from server')
  

Это происходит только из Docker, так как с моей консоли все работает нормально.

Я пробовал оба изображения Docker на python: 3.6 и python: 3.8.

Я также попытался свернуть обе конечные точки изнутри контейнера, и сервер отвечает правильно.

Комментарии:

1. Поскольку запуск конечной точки B занимает 8 минут, я предполагаю, что это очень ресурсоемкий процесс. Я думаю, что происходит то, что контейнер docker для endpointB использует процессор или память более чем на 100%, что приведет к отсутствию ответа на запрос GET, следовательно, вы ошибка. Это конкретно 300 секунд, потому что именно столько времени может потребоваться, чтобы превысить 100% mem. Вы можете проверить это, запустив конечную точку B, затем ssh в контейнер отслеживает использование с помощью watch htop . Процесс завершится сбоем, если использование mem превысит 100%. Вы можете исправить это, выделив больше ресурсов движку docker.

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

Ответ №1:

Вы можете проверить, завершает ли docker соединение, используя nc -l вне контейнера и nc в контейнере для подключения к первому nc, затем оставив их обоих в покое на 10 минут, а затем отправив что-либо, чтобы убедиться, что соединение все еще работает.

Для устранения неполадок в pycurl см.http://pycurl.io/docs/latest/troubleshooting.html#transfer-related-issues.