
私は今日、説明できない問題に直面しており、誰かが私を正しい方向に導いてくれることを願っています。
私は、Python スクリプトを実行している EC2 サーバーのフリートを持っています。ユーザーが私のサーバーに接続すると (ロード バランサー経由で処理されます)、IP アドレス (または PTR) に基づいて逆引き名を取得します。
これまで私が使用していたコードは次のとおりです。
import socket
details = socket.gethostbyaddr(request.user_ip)
print('User PTR is', details[0])
今日気づいたのは、クエリにはgethostbyaddr
数秒かかる可能性があるということです (一部のクエリでは 300 秒もかかりました!!)。平均は 1 秒で、20 秒から 30 秒の間になることがよくあります。
( gethostbyaddr
5 秒でタイムアウトすると言及している人もいますが、私の状況ではそうではないようです)。
さて、 について読んでみると、 (私は Debian 12 を使用しています)を使用して逆順を検索するgethostbyaddr
ようです。私のサーバーでは、そのファイルの内容は次のとおりです。resolv.conf
nameserver 172.31.0.2
search .
そのため、私のサーバーは AWS の VPC DNS リゾルバーに依存しています。
私が行ったのは、コマンド間の時間を追跡しgethostbyaddr
、それが 1 秒より長い場合は、IP とともに期間を表示することでした。
いくつかの IP を持っていたときは、同じコードを同じサーバーで別の Python シェルで実行しましたが、通常は数ミリ秒で結果が返されるか、エラー (未解決のホスト) が返されましたが、通常はすぐに返されました。数秒 (または数分) かかるエラーもありました。
私の仮説Python は、gethostbyaddr
複数のプロセスがあるにもかかわらず、コマンドを順番に実行するためにキューに入れており、そのうちのいくつかがスタックすると、そのクエリに使用するためにいくつかのソケットが解放されるまで、他のコマンドは遅延されます。
それは意味が分かりますか?これは可能ですか?
そこで、別の方法を試してみました。代わりに、arpa DNS (“"[ip-in-reverse].in-addr.arpa.") を使用して逆クエリを作成し、Cloudflare の DNS (1.1.1.1) を使用して自分で直接 DNS をクエリしました。
そうすることで、持続時間が数ミリ秒に短縮され、問題は解決しました。
バグは「ある程度」修正しましたが、なぜ発生したのか正確には説明できません。無効なリバースで EC2 インスタンスに接続しているサーバーがかなりあるため、gethostbyaddr
スタック状態になるのは当然ですが、同じコードを使用している他のプロセスが何らかのキューでスタックしている可能性はありますか? Linux レベルででしょうか?
私の仮説は次のとおりです。
- Debian (Linux) は gethostbyaddr を取得するためのクエリをキューに入れており、一定量のクエリに時間がかかりすぎると、他のクエリは処理される前にキューに入れられます。
- AmazonのDNSに問題があったり、クエリのレート制限や遅延が実装されていたりして、解決に時間がかかるようになっている。
- ???
遅延の原因となる何か見落としている点はありますか?
gethostbyaddr
問題はコードに直接関係しているのではなく、その使用方法に関係しているため、ここではコード サンプルは必要ありません。
助けてくれてありがとう。
答え1
回答が返ってくる速さは、ドメインを担当する DNS サーバーが検索に応答する速さによって決まります。AWS DNS サーバーは、クエリと結果がすでにキャッシュされていない限り、クエリを適切なサーバーに転送します (別のサーバーに転送される場合もあります)。また、DNS は従来 UDP で行われるため、このような外部サーバーはまったく応答しない可能性があり、その場合はタイムアウトが発生するまでリクエストが再試行されます。
一般的に、クエリを外部で解決する必要がある場合、ブロッキング DNS クエリ (gethostbyaddr など) をコードに含めるのは得策ではありません。プログラムを続行するには外部サーバーに完全に依存しますが、クエリにかかる時間を制御できません。