내 크롤러를 실행하는 동안 이상한 소켓 문제가 발생했습니다. 프로토콜 설계로 인해 많은 수의 TCP 소켓을 빠르게 열고 닫을 수 있습니다. 이것은 내가 살아야 할 일입니다. 나는 코드에서 소켓을 올바르게 닫았다고 확신합니다( strace
인쇄를 통해 확인하고 디버그함). 하지만 어떻게든 여전히 시스템의 오픈 소켓 제한에 도달했습니다. Netdat과 같은 도구에서도 열린 소켓 수가 증가한 것으로 나타났습니다. 추가 검사 시. 나는 거기에 수많은 소켓 파일 설명자가 있다는 것을 발견했습니다 /proc/<pid>/fd/
. 내가 실행한 샘플 결과는 다음과 같습니다.
모든 명령은 다음과 같이 실행됩니다.root
# ls /proc/248298/fd/ -l | grep socket | wc -l
522
netstat
그러나 소켓이 연결된 원격을 찾기 위해 실행할 때 시스템 전체의 TIME_WAIT 및 CLOSE_WAIT 소켓이 모두 고려됩니다(netstat가 더 이상 내 프로세스와 연결하지 않기 때문입니다). 이 숫자는 훨씬 낮습니다.
# netstat -tulnap | egrep '(TIME_WAIT|CLOSE_WAIT|248298)' | wc -l
109
나는 그것을 완화 net.ipv4.tcp_tw_reuse
로 설정하려고 시도했지만 성공하지 못했습니다.1
그 이유는 무엇입니까? 한 단계 더 나아가 닫힌 소켓이 여전히 활성 상태로 간주되는 이유는 무엇입니까? 아니면 이 문제를 해결할 수 있는 방법이 있나요?
운영 체제: Linux
배포: Ubuntu 22.04
커널: 5.15
CPU: x64
답변1
이를 일시적인 포트 압력이라고 하며 합법적이지 않은 네트워크 트래픽을 포함하여 다양한 다른 서비스에 대한 많은 연결을 만드는 트래픽이 많은 시스템에 영향을 줄 수 있습니다. 운영 체제는 포트 범위에 대한 RFC 권장 사항과 마찬가지로 이러한 목적으로 예약하는 포트가 다양합니다(RFC 6056, RFC 6335 비교).
Linux에서 가장 간단한 손잡이는 이것입니다 net.ipv4.ip_local_port_range
. 연결이 많은 시스템에서는 가능한 한 크게 설정해야 합니다.
sysctl -w net.ipv4.ip_local_port_range=1024\ 65535
이로 인해 1024~65535 범위의 포트를 사용하는 다른 네트워크 서비스(아마도 NFS용 RPC?)에 문제가 발생할 수 있습니다. 또는 다른 방법의 효율성을 테스트하기 위해 값을 의도적으로 작게 설정하여 문제가 있는 상태를 더 쉽게 재현할 수 있습니다.
sysctl -w net.ipv4.ip_local_port_range=30000\ 30100
물론 이러한 낮은 범위는 임의 서비스를 중단시킬 수 있습니다. 테스트 가상 머신을 사용하거나 테스트 시스템에 대한 콘솔 액세스를 제공하는 것이 좋습니다.
그렇지 않으면 연결이 다양한 상태에서 소비하는 시간을 줄일 수 있는 다양한 손잡이가 있지만(
FIN_WAIT*
카운트가 꺼질 수 있는 상태를 질문에 나열하지 않았음) 너무 낮게 설정하면 위험이 증가할 수 있습니다. 지연되거나 중복된 패킷이 발생하는 등 다양한 문제에 대한 원격 시스템이 속도 제한으로 인해 패킷을 삭제하는 경우에는 이런 일이 발생할 가능성이 없습니다.