python ssl eof ocurrió en violación del protocolo, wantwriteerror, zeroreturnerror

Estoy ejecutando muchas tareas de apio (20,000) usando gevent para la piscina (también para parches de mono). Cada una de estas tareas afecta a servicios de terceros como adwords para extraer datos.

Sigo teniendo tareas fallidas debido a errores SSL subyacentes. A continuación se muestran los seguimientos de stack de algunas de las excepciones (en ningún orden en particular, estos son fallas de tareas separadas). También recibo WantWriteError y ZeroReturnError de vez en cuando, pero el error EOF parece ser el que más aparece.

Estos errores ocurren al usar diferentes bibliotecas de clientes como googleads (suds library for soap communication), así como solicitudes y búsqueda de resultados. Supongo que algunas de estas bibliotecas usan urllib3 mientras que otras usan urllib2, etc.

Ha habido mucha información sobre el problema EOF y forzando TLSv1 pero parece que no puedo encontrar una resolución que funcione.

No estoy seguro de si estoy ejecutando demasiadas solicitudes a la vez, si hay algo bloqueando o qué; Cualquier ayuda sería muy apreciada, me estoy sacando el pelo.

Traceback (most recent call last): ... File "/srv/reporting/src/reporting/stats/adwords/client.py", line 58, in _awql_report downloader = self._get_client(client_id).GetReportDownloader(version=self.REPORT_DOWNLOADER_VERSION) File "/usr/local/lib/python2.7/dist-packages/googleads/adwords.py", line 283, in GetReportDownloader return ReportDownloader(self, version, server) File "/usr/local/lib/python2.7/dist-packages/googleads/adwords.py", line 400, in __init__ proxy=proxy_option, cache=self._adwords_client.cache).wsdl.schema File "/usr/local/lib/python2.7/dist-packages/suds/client.py", line 115, in __init__ self.wsdl = reader.open(url) File "/usr/local/lib/python2.7/dist-packages/suds/reader.py", line 150, in open d = self.fn(url, self.options) File "/usr/local/lib/python2.7/dist-packages/suds/wsdl.py", line 136, in __init__ d = reader.open(url) File "/usr/local/lib/python2.7/dist-packages/suds/reader.py", line 74, in open d = self.download(url) File "/usr/local/lib/python2.7/dist-packages/suds/reader.py", line 92, in download fp = self.options.transport.open(Request(url)) File "/usr/local/lib/python2.7/dist-packages/suds/transport/https.py", line 62, in open return HttpTransport.open(self, request) File "/usr/local/lib/python2.7/dist-packages/suds/transport/http.py", line 67, in open return self.u2open(u2request) File "/usr/local/lib/python2.7/dist-packages/suds/transport/http.py", line 132, in u2open return url.open(u2request, timeout=tm) 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 1216, in https_open return self.do_open(httplib.HTTPSConnection, req) File "/usr/lib/python2.7/urllib2.py", line 1178, in do_open raise URLError(err) URLError:  Traceback (most recent call last): ... File "/srv/reporting/src/reporting/stats/analytics/client.py", line 57, in get_access_token response = requests.post('https://accounts.google.com/o/oauth2/token', data) File "/usr/local/lib/python2.7/dist-packages/requests/api.py", line 88, in post return request('post', url, data=data, **kwargs) File "/usr/local/lib/python2.7/dist-packages/requests/api.py", line 44, in request return session.request(method=method, url=url, **kwargs) File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 456, in request resp = self.send(prep, **send_kwargs) File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 559, in send r = adapter.send(request, **kwargs) File "/usr/local/lib/python2.7/dist-packages/requests/adapters.py", line 382, in send raise SSLError(e, request=request) SSLError: [Errno bad handshake] (-1, 'Unexpected EOF') Traceback (most recent call last): ... self.es.index(index=self.INDICE, doc_type=self.ROOT_CLASS.__name__, body=self.export(obj), id=obj.id) File "/usr/local/lib/python2.7/dist-packages/elasticsearch/client/utils.py", line 68, in _wrapped return func(*args, params=params, **kwargs) File "/usr/local/lib/python2.7/dist-packages/elasticsearch/client/__init__.py", line 213, in index _make_path(index, doc_type, id), params=params, body=body) File "/usr/local/lib/python2.7/dist-packages/elasticsearch/transport.py", line 284, in perform_request status, headers, data = connection.perform_request(method, url, params, body, ignore=ignore, timeout=timeout) File "/usr/local/lib/python2.7/dist-packages/elasticsearch/connection/http_requests.py", line 44, in perform_request response = self.session.request(method, url, data=body, timeout=timeout or self.timeout) File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 456, in request resp = self.send(prep, **send_kwargs) File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 559, in send r = adapter.send(request, **kwargs) File "/usr/local/lib/python2.7/dist-packages/requests/adapters.py", line 327, in send timeout=timeout File "/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/connectionpool.py", line 493, in urlopen body=body, headers=headers) File "/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/connectionpool.py", line 319, in _make_request httplib_response = conn.getresponse(buffering=True) File "/usr/lib/python2.7/httplib.py", line 1030, in getresponse response.begin() File "/usr/lib/python2.7/httplib.py", line 407, in begin version, status, reason = self._read_status() File "/usr/lib/python2.7/httplib.py", line 365, in _read_status line = self.fp.readline() File "/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/contrib/pyopenssl.py", line 273, in readline data = self._sock.recv(self._rbufsize) File "/usr/local/lib/python2.7/dist-packages/OpenSSL/SSL.py", line 995, in recv self._raise_ssl_error(self._ssl, result) File "/usr/local/lib/python2.7/dist-packages/OpenSSL/SSL.py", line 851, in _raise_ssl_error raise ZeroReturnError() ZeroReturnError 

Así que vamos a desglosar esto por cada bloque de rastreo. El primero termina con:

  File "/usr/lib/python2.7/urllib2.py", line 1178, in do_open raise URLError(err) URLError:  

Esto viene de urllib2. El hecho de que esto reciba un EOF me hace pensar que el servidor cerró la conexión mientras esperaba que ese “hilo” volviera a leer desde el socket. Es posible que desee utilizar más time.sleep(0) para ceder a gevent.

El segundo rastreo viene de las solicitudes:

  File "/usr/local/lib/python2.7/dist-packages/requests/adapters.py", line 382, in send raise SSLError(e, request=request) SSLError: [Errno bad handshake] (-1, 'Unexpected EOF') 

El [Errno bad handshake] me haría pensar que este es un problema al establecer la conexión que podría ser causado por un EOF inesperado. ¿Es eso causado por el uso de gevent ? Soy incierto

El rastreo final es definitivamente también de solicitudes, pero también está saliendo de PyOpenSSL y no está siendo detectado por urllib3 o solicitudes.

  File "/usr/local/lib/python2.7/dist-packages/OpenSSL/SSL.py", line 851, in _raise_ssl_error raise ZeroReturnError() ZeroReturnError 

Hice algunas búsquedas y descubrí que “De acuerdo con los documentos de pyOpenSSL, ZeroReturnError significa que la conexión SSL se ha cerrado de forma limpia”. Esto me dice que el servidor volvió a cerrar la conexión porque tardaste demasiado en leer cualquier cosa desde el socket.

En resumen, creo que necesita rendir explícitamente más a menudo para asegurarse de que no surjan estos problemas de socket. Eso es solo una suposición, así que tómalo con un grano de sal.