Python gethostbyaddr ist langsam

Python gethostbyaddr ist langsam

Ich stehe heute vor einem Problem, das ich nicht erklären kann, und ich hoffe, dass mir jemand weiterhelfen kann.

Ich habe eine Flotte von EC2-Servern, auf denen ein Python-Skript ausgeführt wird. Wenn sich ein Benutzer mit meinen Servern verbindet (über einen Load Balancer), erhalte ich unter anderem seinen umgekehrten Namen basierend auf seiner IP-Adresse (oder PTR).

Bisher habe ich folgenden Code verwendet:

import socket

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

Was mir heute aufgefallen ist, ist, dass die Abfrage gethostbyaddreinige Sekunden dauern kann (bei manchen Abfragen dauerte es sogar 300 Sekunden!!). Der Durchschnitt liegt bei 1 Sekunde und häufig zwischen 20 und 30 Sekunden!

(Einige erwähnen gethostbyaddrein Timeout nach 5 Sekunden, was in meiner Situation nicht der Fall zu sein scheint).

Wenn man jetzt darüber liest gethostbyaddr, scheint es, dass es resolv.conf(ich verwende Debian 12) verwendet, um den Umkehrwert zu finden. Auf meinen Servern ist der Inhalt dieser Datei:

nameserver 172.31.0.2
search .

Meine Server verlassen sich also auf den VPC-DNS-Resolver von AWS.

Ich habe die Zeit zwischen den Befehlen verfolgt gethostbyaddrund, wenn sie länger als 1 Sekunde war, die Dauer zusammen mit der IP angezeigt.

Als ich einige IPs hatte, führte ich denselben Code auf demselben Server, aber auf einer anderen Python-Shell aus und erhielt oft innerhalb weniger ms ein Ergebnis oder einen Fehler (nicht aufgelöster Host), im Allgemeinen ziemlich schnell. Bei einigen traten Fehler auf, die Sekunden (oder sogar Minuten) brauchten, bis sie auftraten.

Meine Hypothesebesteht darin, dass Python die Befehle in die Warteschlange stellt gethostbyaddr, um sie trotz mehrerer Prozesse nacheinander auszuführen. Wenn einige davon hängen bleiben, werden die anderen verzögert, bis einige Sockets für die Verwendung für diese Abfrage freigegeben werden.

Ist das sinnvoll? Ist das möglich?

Also habe ich eine Alternative ausprobiert: Stattdessen habe ich die umgekehrte Abfrage mithilfe des Arpa-DNS („[ip-in-reverse].in-addr.arpa.“) erstellt und den DNS selbst direkt abgefragt, indem ich den DNS von Cloudflare (1.1.1.1) verwendet habe.

Dadurch verringerte sich die Dauer auf einige ms, wodurch das Problem behoben wurde.

Ich habe den Fehler „irgendwie“ behoben, kann aber nicht genau erklären, warum er aufgetreten ist. Ich habe ziemlich viele Server, die sich mit meiner EC2-Instanz verbinden, aber eine ungültige Rückwärtsverbindung haben, daher gethostbyaddrmacht es Sinn, dass das Problem hängen bleibt, aber ist es möglich, dass ein anderer Prozess, der denselben Code verwendet, in einer Warteschlange hängen bleibt? Vielleicht auf Linux-Ebene?

Hier ist meine Hypothese:

  1. Debian (Linux) stellt die Abfragen zum Abrufen von gethostbyaddr in eine Warteschlange. Wenn eine bestimmte Anzahl zu lange dauert, werden die anderen vor der Verarbeitung in eine Warteschlange gestellt.
  2. Amazon hat Probleme mit seinem DNS oder hat eine Ratenbegrenzung oder Verzögerung für die Abfragen implementiert, wodurch die Auflösung länger dauert
  3. ???

Was übersehe ich, das die Verzögerungen erklären könnte?

Ein Codebeispiel ist hier nicht erforderlich, da das Problem nicht direkt mit dem Code zusammenhängt, sondern mit seiner gethostbyaddrVerwendung.

Ich danke Ihnen für Ihre Hilfe.

Antwort1

Wie schnell Sie eine Antwort erhalten, hängt davon ab, wie schnell der für die Domäne zuständige DNS-Server die Abfrage beantwortet. Der AWS DNS-Server leitet die Abfrage einfach an den entsprechenden Server weiter (der sie möglicherweise an einen anderen weiterleitet), es sei denn, die Abfrage und das Ergebnis sind bereits zwischengespeichert. Und da DNS traditionell mit UDP erfolgt, antworten solche externen Server möglicherweise einfach überhaupt nicht. In diesem Fall werden die Anfragen wiederholt, bis ein Timeout auftritt.

Im Allgemeinen ist es keine gute Idee, eine blockierende DNS-Abfrage (wie gethostbyaddr) in Ihren Code einzubinden, wenn die Abfrage extern aufgelöst werden muss. Sie sind vollständig von einem externen Server abhängig, um in Ihrem Programm fortzufahren, haben aber keine Kontrolle darüber, wie lange die Abfrage dauern wird.

verwandte Informationen