
오늘 저는 설명할 수 없는 문제에 직면해 있습니다. 누군가가 저를 올바른 방향으로 인도해 줄 수 있기를 바랍니다.
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를 사용하고 있습니다) 반대를 찾기 위해 (저는 Debian 12를 사용하고 있습니다)를 gethostbyaddr
사용하는 것으로 보입니다 . resolv.conf
내 서버에서 해당 파일의 내용은 다음과 같습니다.
nameserver 172.31.0.2
search .
따라서 내 서버는 AWS의 VPC DNS 확인자에 의존하고 있습니다.
내가 한 일은 명령 사이의 시간을 추적 gethostbyaddr
하고 1초보다 긴 경우 IP와 함께 지속 시간을 표시하는 것입니다.
IP가 있을 때 동일한 서버에서 다른 Python 셸에서 동일한 코드를 실행했는데 일반적으로 몇 ms 안에 결과를 얻거나 오류(해결되지 않은 호스트)를 얻는 경우가 많았습니다. 일부에는 표시되는 데 몇 초(또는 몇 분)가 걸릴 수 있는 오류가 있었습니다.
내 가설Python은 gethostbyaddr
여러 프로세스가 있음에도 불구하고 명령을 순차적으로 실행하기 위해 대기열에 대기하고 있으며, 그 중 일부가 멈춘 경우 해당 쿼리에 사용할 수 있도록 일부 소켓이 해제될 때까지 나머지는 지연됩니다.
그게 말이 되나요? 이것이 가능한가 ?
그래서 대안을 시도했습니다. 대신 arpa DNS("[ip-in-reverse].in-addr.arpa.")를 사용하여 역방향 쿼리를 구축하고 Cloudflare의 DNS(1.1.1.1)를 사용하여 직접 DNS에 쿼리했습니다. 1.1).
그렇게 하면 지속 시간이 몇 ms로 줄어들어 문제가 해결되었습니다.
나는 버그를 "어느 정도" 고쳤지만 왜 그런 일이 일어났는지는 정확히 설명할 수 없습니다. 잘못된 역방향으로 EC2 인스턴스에 연결하는 서버가 꽤 많기 때문에 멈추는 것이 gethostbyaddr
합리적이지만 동일한 코드를 사용하는 다른 프로세스가 일부 대기열에 걸릴 수 있습니까? 어쩌면 리눅스 수준에서요?
내 가설은 다음과 같습니다.
- Debian(Linux)은 gethostbyaddr을 검색하기 위해 쿼리를 대기열에 추가하고 특정 양이 너무 오래 걸리면 나머지는 처리되기 전에 대기열에 넣습니다.
- Amazon은 DNS에 문제가 있거나 쿼리에 대해 일부 속도 제한 또는 지연을 구현하여 해결 시간이 길어졌습니다.
- ???
지연을 설명할 수 있는 내가 무엇을 놓치고 있습니까?
문제는 코드와 직접적인 관련이 없지만 사용 방법에 관한 것이므로 여기에는 코드 샘플이 필요하지 않습니다 gethostbyaddr
.
도움을 주셔서 감사합니다.
답변1
답변을 얻는 속도는 도메인을 담당하는 DNS 서버가 조회에 얼마나 빨리 응답하는지에 따라 달라집니다. AWS DNS 서버는 쿼리와 결과가 이미 캐시되지 않은 한 쿼리를 적절한 서버로 전달합니다(다른 서버로 전달할 수도 있음). 그리고 DNS는 전통적으로 UDP를 사용하여 수행되므로 이러한 외부 서버는 전혀 응답하지 않을 수 있으며, 이 경우 시간 초과가 발생할 때까지 요청이 재시도됩니다.
일반적으로 쿼리를 외부에서 해결해야 하는 경우 차단 DNS 쿼리(예: gethostbyaddr)를 코드에 포함하는 것은 좋지 않습니다. 프로그램을 계속 진행하려면 일부 외부 서버에 전적으로 의존하지만 쿼리에 걸리는 시간을 제어할 수는 없습니다.