베하~
작은뉴진입니다.
앞서 TIME_WAIT 소켓에 대해 알아보았고, 연결이 종료된 이후에도 소켓을 바로 정리하지 않아 발생할 수 있는 문제점을 방지할 수 있다고 말씀드렸었어요. 기억하시나요?
하지만 Timewait 대기 상태에 있는 소켓이 많아지는 경우 로컬 포트가 고갈 될 수가 있는데요,
이 문제를 해결할 수 있는 방법들에 대해 알아볼게요.
첫 번째로는 커널 파라미터를 이용하는 방법이 있어요.
TIME_WAIT 소켓을 처리하는 커널의 파라미터 중에 net.ipv4.tcp_tw_reuse는 외부로 요청할 때 TIME_WAIT 소켓을 재사용할 수 있게 해줍니다.
주의할점은 net.ipv4.tcp_tw_reuse는 timestamp 기능과 함께 사용해야 하고 net.ipv4.tcp_timestamps 값이 반드시 1이어야 해요.
두 번째로는 Connection Pool 방식을 사용하는 방법이 있어요.
로컬 포트를 reuse를 하는 것은 임시방편책이며, 근본적인 원인을 해결하는 방법으로 Connection Pool 방식이 존재합니다.
TIME_WAIT 소켓이 쌓이는 문제는 먼저 연결을 끊기 때문에 TIME_WAIT 소켓이 생기게 되며,
이후의 통신을 위해서 다시 연결을 맺어야 해서 리소스 낭비가 발생하게 됩니다.
이럴 때 Connection Pool 방법이 방안이 될 수 있어요.
미리 소켓을 열어놓고 요청을 처리하기 때문에 불필요한 TCP 연결 맺기/끊기 과정이 없어서 더 빠르게 응답을 할 수 있습니다.
세 번째 방법으로는 역시나 커널 파라미터를 사용하는 방법인데요,
net.ipv4.tcp_tw_recycle 파라미터는 나갈때 사용하는 로컬 포트에서 TIME_WAIT 상태의 소켓을 재사용할 수 있게 해주는 net.ipv4.tw_reuse 와는 반대로,
서버가 TIME_WAIT 상태의 소켓을 빠르게 회수하고 재활용할 수 있게 해주는 파라미터에요.
하지만 같은 NAT를 사용하는 디바이스에서 요청이 들어올 시 동일한 IP를 가진 목적지에서 기존보다 더 작은 Timestamp를 가지고 통신 연결을 요청하기 때문에 잘못된 연결 요청으로 판단하고 패킷을 처리하지 않고 버리는 경우가 있기에 웹 서버에서는 이 파라미터를 사용하지 않아요.
마지막으로 가장 권장되는 방법인데요, 바로 keepalive 를 사용하는 방법입니다.
TIME_WAIT 소켓을 완전히 없앨 수는 없지만 줄일 수 있는 방법으로, 한번 맺은 세션을 요청의 끝나더라도 유지해주는 기능이에요.
keepalive가 지정되어 있지 않다면 외부에서 요청이 들어오고 난 후 클라이언트 측에서 요청할 내용이 더 있다고 해도 서버가 먼저 끊기 때문에 요청마다 새로운 소켓을 열어야하는데요,
서버의 입장에서 keepalive로 세션을 유지해주면 TIME_WAIT 소켓을 줄일 수 있으며, 불필요한 TCP 연결 맺기/끊기 과정이 사라지기 때문에 서비스의 응답 속도도 더 빠르게 향상 시킬 수 있습니다.
keepalive를 사용하는데 필요한 커널 파라미터는 세 가지가 있습니다.
1. net.ipv4.tcp_keepalive_time
TCP 세션에 대해 keepalive를 유지하는 시간
2. net.ipv4.tcp_keepalive_probes
keepalive가 끊어졌다고 판단하고 세션을 정리하는 동안 보낼 재전송 패킷 수
3. net.ipv4.tcp_keepalive_intvl
첫 번째 health_check 이후 재전송 패킷을 보내는데 걸리는 패킷 사이의 주기
처음에 설정한 tcp_keepalive_time이 지난 후 keepalive 확인 패킷을 보내게 되는데, 이 패킷에 응답이 없으면 몇 초 후에 재전송 패킷을 보낼 것인지 그 시간을 정의합니다.
keepalive 기능은 잘못된 커넥션 유지 소켓인 좀비 커넥션을 방지하는데 특히 효과가 있습니다.
keepalive 설정이 되어있지 않으면 세그먼트 유실 시 연결이 끊겼는지 상대방이 알 수 없지만 keepalive 를 사용할 경우에는 주기적으로 keepalive 패킷을 보내기 때문에 응답이 오지 않으면 상대방측에서 연결이 끊겼는지를 알 수 있지요.
이렇게 3, 4-way handshake 부터 keepalive까지의 긴 공부가 끝났어요!
다음에도 재밌는 주제로 돌아올게요
안녕~~~😚
'Network' 카테고리의 다른 글
[Network] CIDR 계산법 (1) | 2023.12.08 |
---|---|
식별자(MAC주소/IP주소 /Port번호) (1) | 2023.11.24 |
TIME_WAIT (0) | 2023.11.13 |
URI, URL, URN (0) | 2023.11.05 |
TCP와 UDP의 차이(2) (0) | 2023.11.03 |
댓글