
我今天面臨一個無法解釋的問題,我希望有人能引導我走向正確的方向。
我有一組運行 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 秒超時,但在我的情況下似乎並非如此)。
現在,閱讀有關 的內容gethostbyaddr
,它似乎使用resolv.conf
(我正在使用 Debian 12)來查找相反的內容。在我的伺服器中,該文件的內容是:
nameserver 172.31.0.2
search .
所以我的伺服器依賴AWS的VPC DNS解析器。
我所做的是追蹤命令之間的時間gethostbyaddr
,如果超過 1 秒,則顯示持續時間以及 IP。
當我有一些 IP 時,我在同一台伺服器上但在另一個 Python shell 上運行相同的程式碼,通常會在幾毫秒內得到結果,或者出現錯誤(無法解析的主機),通常很快。有些錯誤可能需要幾秒鐘(甚至幾分鐘)才能顯示出來。
我的假設問題在於,Python 正在對gethostbyaddr
命令進行排隊以按順序運行它們,儘管有多個進程,並且如果其中一些進程被卡住,其他進程將被延遲,直到某些套接字被釋放以用於該查詢。
這樣有道理嗎?這可能嗎 ?
因此,我嘗試了另一個選擇:相反,我使用arpa DNS(「[ip-in-reverse].in-addr.arpa.」)建立了反向查詢,並使用Cloudflare 的DNS(1.1.1.1)自己直接查詢DNS。
這樣做可以使持續時間減少到幾毫秒,從而解決了問題。
我「有點」修復了這個錯誤,但無法準確解釋它發生的原因。我有相當多的伺服器透過無效的反向連接到我的 EC2 實例,因此卡住gethostbyaddr
是有道理的,但是使用相同程式碼的其他進程是否有可能卡在某個佇列中?也許在 Linux 層級?
這是我的假設:
- Debian (Linux) 正在排隊查詢以檢索 gethostbyaddr,當一定數量的請求花費太長時間時,其他請求會在處理之前放入佇列中
- 亞馬遜的 DNS 存在一些問題,或對查詢實施了一些速率限製或延遲,導致解析時間更長
- ???
我錯過了什麼可以解釋延遲?
這裡不需要程式碼範例,因為問題與程式碼沒有直接關係,而是與如何gethostbyaddr
使用有關。
感謝您的幫助。
答案1
您獲得答案的速度取決於負責該網域的 DNS 伺服器回答查找的速度。 AWS DNS 伺服器只會將查詢轉送到適當的伺服器(可能會轉送到另一台伺服器),除非查詢和結果已快取。由於 DNS 傳統上是使用 UDP 完成的,因此外部伺服器可能根本不會回應,在這種情況下,請求將重試,直到發生逾時。
一般來說,當查詢需要從外部解析時,在程式碼中包含阻塞 DNS 查詢(如 gethostbyaddr)是一個壞主意。您完全依賴某些外部伺服器來繼續您的程序,但無法控制查詢將花費多長時間。