Python gethostbyaddr es lento

Python gethostbyaddr es lento

Hoy me enfrento a un problema que no puedo explicar y espero que alguien pueda orientarme en la dirección correcta.

Tengo una flota de servidores EC2 que ejecutan un script en Python. Cuando un usuario se conecta a mis servidores (manejados a través de un Load Balancer), una cosa que hago es obtener su nombre inverso según su dirección IP (o PTR).

Hasta ahora, este es el código que estaba usando:

import socket

details = socket.gethostbyaddr(request.user_ip)
print('User PTR is', details[0])

De lo que me di cuenta hoy fue que la consulta gethostbyaddrpodía tardar unos segundos (¡¡alguna consulta incluso tardó 300 segundos!!). ¡El promedio es de 1 segundo y un número frecuente entre 20 y 30 segundos!

(Algunos mencionan gethostbyaddrtener un tiempo de espera de 5 segundos, lo que no parece ser el caso en mi situación).

Ahora, al leer sobre gethostbyaddr, parece que usa resolv.conf(estoy usando Debian 12) para encontrar lo contrario. En mis servidores, el contenido de ese archivo es:

nameserver 172.31.0.2
search .

Entonces mis servidores dependen del solucionador de DNS VPC de AWS.

Lo que hice fue rastrear el tiempo entre el gethostbyaddrcomando y, si fue superior a 1 segundo, mostrar la duración, junto con la IP.

Cuando tenía algunas IP, ejecutaba el mismo código en el mismo servidor pero en otro shell de Python y, a menudo, obtenía un resultado en unos pocos ms o un error (host sin resolver), en general con bastante rapidez. Algunos tenían errores que podían tardar segundos (o incluso minutos) en aparecer.

mi hipotesises que Python está poniendo en cola el gethostbyaddrcomando para ejecutarlos secuencialmente, a pesar de tener múltiples procesos, y si algunos de ellos están atascados, los demás se retrasarán hasta que algunos sockets queden libres para usarse en esa consulta.

¿Tiene eso sentido? Es posible ?

Así que probé una alternativa: en su lugar, construí la consulta inversa usando el DNS arpa ("[ip-in-reverse].in-addr.arpa.") y consulté el DNS yo mismo, directamente, usando el DNS de Cloudflare (1.1. 1.1).

Al hacerlo, la duración se redujo a unos pocos ms, lo que solucionó el problema.

"Más o menos" arreglé el error, pero no puedo explicar exactamente por qué sucedió. Tengo bastantes servidores que se conectan a mi instancia EC2 con una inversión inválida, por lo que tener el gethostbyaddrbloqueo tiene sentido, pero ¿es posible que otro proceso que use el mismo código pueda estar bloqueado en alguna cola? ¿Quizás a nivel de Linux?

Aquí está mi hipótesis:

  1. Debian (Linux) está poniendo en cola las consultas para recuperar gethostbyaddr y cuando una cierta cantidad tarda demasiado, las demás se ponen en cola antes de ser procesadas.
  2. Amazon tiene algunos problemas con su DNS o implementó alguna limitación de velocidad o retraso en las consultas, lo que hace que la resolución sea más larga.
  3. ???

¿Qué me falta que pueda explicar los retrasos?

No es necesario un ejemplo de código aquí, ya que el problema no está relacionado directamente con el código, sino con cómo gethostbyaddrse utiliza.

Gracias por su ayuda.

Respuesta1

La rapidez con la que obtenga una respuesta depende de la rapidez con la que el servidor DNS responsable del dominio responderá a la búsqueda. El servidor DNS de AWS simplemente reenviará la consulta al servidor apropiado (que podría reenviarla a otro) a menos que la consulta y el resultado ya estén almacenados en caché. Y dado que el DNS se realiza tradicionalmente con UDP, es posible que dichos servidores externos simplemente no respondan en cuyo caso las solicitudes se reintentarán hasta que se agote el tiempo de espera.

En general, es una mala idea incluir una consulta DNS de bloqueo (como gethostbyaddr) en su código, cuando la consulta debe resolverse externamente. Depende completamente de algún servidor externo para continuar con su programa, pero no tiene control sobre cuánto tiempo llevará la consulta.

información relacionada