Nice programing

서버 측에서 많은 TIME_WAIT의 비용은 얼마입니까?

nicepro 2020. 12. 12. 12:28
반응형

서버 측에서 많은 TIME_WAIT의 비용은 얼마입니까?


서버에 단기 연결을 많이하는 클라이언트가 있다고 가정 해 보겠습니다.

클라이언트가 연결을 닫으면 TIME_WAIT클라이언트 측에 많은 포트가 있습니다 . 클라이언트에 로컬 포트가 부족하므로 새 연결 시도를 빠르게 할 수 없게됩니다.

서버가 연결을 닫으면 TIME_WAIT서버 측에서 많은 것을 볼 수 있습니다. 그러나 이것이 해를 끼치나요? 클라이언트 (또는 다른 클라이언트)는 로컬 포트가 부족하지 않기 때문에 연결을 계속 시도 할 수 TIME_WAIT있으며 서버 측에서 상태 수가 증가합니다. 결국 어떻게 되나요? 나쁜 일이 일어나나요? (느림, 충돌, 연결 끊김 등)

내 질문은 "의 목적은 TIME_WAIT무엇입니까?" 가 아닙니다. 그러나 " TIME_WAIT서버에 너무 많은 상태 가 있으면 어떻게됩니까 ?" TCP / IP에서 연결이 닫힐 때 어떤 일이 발생하고 왜 TIME_WAIT상태가 필요한지 이미 알고 있습니다. 문제를 해결하려는 것이 아니라 잠재적 인 문제가 무엇인지 알고 싶습니다.

간단히 말해서 netstat -nat | grep :8080 | grep TIME_WAIT | wc -lprints 라고합시다 100000. 무슨 일이 일어날 지? O / S 네트워크 스택이 느려지나요? "열린 파일이 너무 많음"오류? 아니면 걱정할 것이 없습니까?


의 각 소켓 TIME_WAIT은 커널에서 약간의 메모리 소비하며 일반적으로 ESTABLISHED소켓 보다 다소 적지 만 여전히 중요합니다. 충분히 큰 수는 커널 메모리를 소모하거나 해당 메모리가 다른 용도로 사용될 수 있기 때문에 적어도 성능을 저하시킬 수 있습니다. TIME_WAIT소켓은 열린 파일 설명자를 보유하지 않으므로 (올바르게 닫혔다 고 가정) "너무 많은 열린 파일"오류에 대해 걱정할 필요가 없습니다.

소켓은 또한 해당 특정 src/ dstIP 주소 및 포트를 연결하므로 TIME_WAIT간격 기간 동안 재사용 할 수 없습니다 . (이것은 TIME_WAIT상태 의 의도 된 목적입니다 .) 동일한 포트 쌍으로를 다시 연결해야하는 경우가 아니면 포트를 묶는 것은 일반적으로 문제가되지 않습니다. 대부분의 경우 한쪽은 잘 알려진 포트에 고정 된 한쪽 만 임시 포트를 사용합니다. 그러나 TIME_WAIT동일한 두 IP 주소간에 반복적으로 자주 연결하는 경우 매우 많은 수의 소켓이 임시 포트 공간을 소모 할 수 있습니다. 이는이 특정 IP 주소 쌍에만 영향을 미치며 다른 호스트와의 연결 설정에는 영향을 미치지 않습니다.


각 연결은 튜플 (서버 IP, 서버 포트, 클라이언트 IP, 클라이언트 포트)로 식별됩니다. 결정적으로 TIME_WAIT연결 (서버 측이든 클라이언트 측이든)은 각각 이러한 튜플 중 하나를 차지합니다.

TIME_WAIT클라이언트 측 에서 s를 사용하면 더 이상 연결을 할 수없는 이유를 쉽게 알 수 있습니다. 더 이상 로컬 포트가 없습니다. 그러나 동일한 문제가 서버 측에도 적용됩니다 . 단일 클라이언트에 대해 64k 연결 TIME_WAIT상태 가되면 해당 클라이언트에서 더 이상 연결 허용 할 수 없습니다 . 이전 연결과 연결 간의 차이를 구분할 방법이 없기 때문입니다. 새 연결-두 연결 모두 동일한 튜플로 식별됩니다. 이 경우 서버는 RST해당 클라이언트의 새 연결 시도에 s를 다시 보내야 합니다.


지금까지의 결과 :

서버가 시스템 호출을 사용하여 소켓을 닫아도 TIME_WAIT 상태가되면 파일 디스크립터가 해제되지 않습니다. 파일 설명자는 나중에 TIME_WAIT 상태가 사라질 때 (즉, 2 * MSL 초 후) 해제됩니다. 따라서 TIME_WAIT가 너무 많으면 서버 프로세스에서 '너무 많은 열린 파일'오류가 발생할 수 있습니다.

O / S TCP / IP 스택이 적절한 데이터 구조 (예 : 해시 테이블)로 구현되었다고 생각하므로 총 TIME_WAIT 수가 O / S TCP / IP 스택의 성능에 영향을주지 않아야합니다. TIME_WAIT 상태의 소켓을 소유 한 프로세스 (서버) 만 문제가 발생합니다.


여러 다른 클라이언트 IP에서 서버 IP로 많은 연결이있는 경우 연결 추적 테이블의 제한이 발생할 수 있습니다.

검사:

sysctl net.ipv4.netfilter.ip_conntrack_count
sysctl net.ipv4.netfilter.ip_conntrack_max

모든 src ip / port 및 dest ip / port 튜플에 대해 추적 테이블에 net.ipv4.netfilter.ip_conntrack_max 만있을 수 있습니다. 이 제한에 도달하면 "nf_conntrack : table full, dropping packet."이라는 메시지가 로그에 표시됩니다. 서버는 추적 테이블에 다시 공간이 생길 때까지 새로운 수신 연결을 수락하지 않습니다.

이 제한은 임시 포트가 다 떨어지기 오래 전에 영향을 미칠 수 있습니다.


내 시나리오에서는 파일을 반복적으로 예약하는 스크립트를 실행했습니다. 내 제품은 일부 계산을 수행하고 클라이언트에 응답을 보냅니다. 즉 클라이언트가 각 파일의 응답을 얻기 위해 반복적 인 http 호출을 만들고 있습니다. 약 150 개의 파일이 예약 된 경우 서버의 소켓 포트가 time_wait 상태에서 http 연결을 여는 클라이언트에서 예외가 발생합니다.

 Error : [Errno 10048] Only one usage of each socket address (protocol/network address/port) is normally permitted

그 결과 내 응용 프로그램이 중단되었습니다. 스레드가 대기 상태에 있거나 무슨 일이 일어 났는지 모르겠지만 모든 프로세스를 종료하거나 응용 프로그램을 다시 시작해야 다시 작동합니다.

기본적으로 240 초이기 때문에 대기 시간을 30 초로 줄 였지만 작동하지 않았습니다.

그래서 기본적으로 내 응용 프로그램이 응답하지 않도록 전체적인 영향이 중요했습니다.


서버가 들어오는 연결 (기존 TIMED_WAIT의 기간 동안)에 할당 할 포트가 부족할 수있는 것처럼 보입니다 (DOS 공격의 경우).

참고 URL : https://stackoverflow.com/questions/1803566/what-is-the-cost-of-many-time-wait-on-the-server-side

반응형