본문 바로가기
Network

keepalive

by BTC_작은뉴진 2023. 11. 17.

베하~

작은뉴진입니다.


 

앞서 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

댓글