[Becoming SE] What is Keep-alive?

DaBeen Yi
7 min readApr 22, 2021

--

  • Keep-alive에 대한 설명
  • HTTP keep-alive와 TCP keep-alive 비교

지난 번 AWS ELB 포스팅을 작성할 때 잠시 언급하였던 keep-alive에 대해 조금 더 자세히 다뤄보고자 한다.

일단 가장 기본적으로 Keep-alive란 무엇인가?

위키피디아에 따르면 Keep-alive란 ‘A keepalive (KA) is a message sent by one device to another to check that the link between the two is operating, or to prevent the link from being broken.’ 이라고 한다.

즉, 두 장비 간의 연결이 잘 맺어져있는지 확인하거나 연결이 끊어짐을 방지하는 용도로 쓰이는 메세지 정도로 설명할 수 있다.

이렇게 설명을 들으니 용어가 굉장히 직관적이다.

‘나 계속 살아있으니 연결 끊지마! 👻’

그럼 이 Keep-alive는 어디에서 사용되는가?

지금 다시 생각해보면 이전 포스팅에서 내가 유독 Idle timeout과 Keep-alive 을 헷갈렸던 이유 중 하나는 ‘어디에서 Keep-alive이 쓰는지 몰라서’였던 것 같다. 이게 어디서 쓰이는 옵션인지 모르니 LB에서 Keep-alive와 Idle timeout을 둘 다 쓰는건지.. AWS에서는 EC2 인스턴스에서의 Keep-alive 활성화를 권고한다는데 그럼 서버 쪽에서만 적용이 된다는건지 개념이 명확하게 잡히지 않았다. 🤔

이 답변에 대해서도 결론부터 말하자면 Keep-alive는
- L7 (HTTP)
- L4 (TCP)
에서 사용된다.

그래서 Keep-alive에 대해 찾아보면 대다수의 포스팅들이 HTTP Keep-alive 혹은 TCP Keep-alive에 대한 내용으로 나누어져 설명되어있다.

흥미로운 점은 Keep-alive라는 이름은 동일하게 사용하지만 HTTP Keep-alive와 TCP Keep-alive는 그 성격이 좀 다르다. 이 부분은 바로 다음 섹션에서 설명하려고 한다.

HTTP Keep-alive vs TCP Keep-alive?

이름은 같은데 성격이 다른 두 옵션

HTTP Keep-alive의 경우에는 ‘연결을 유지한다.’ 라는 느낌보다는 ‘일정 시간 기다려본다.’라는 느낌이 강하다. 그래서 HTTP Keep-alive 값으로 설정된 시간이 지나면 FIN 패킷을 날려 연결을 종료한다.

반면에 TCP Keep-alive의 경우, ‘연결을 유지한다.’는 느낌이 강하다. 실제로 TCP Keep-alive 동작 방식을 보면 주기적으로 Keep-alive packet을 날려서 그에 대한 응답이 오면 (연결을 유지하는) 타이머를 초기화한다. 즉, 상태 확인 메세지에 대해 상대방으로부터 응답이 온다면 그 연결은 계속해서 유지를 하는 것이다.

이런 차이점은 각 각의 설정을 보더라도 알 수 있다.

아래 각 각의 설정을 보다시피 HTTP Keep-alive의 경우는 ‘기능의 활성화 여부’ 그리고 ‘Timeout 시간’만을 설정할 수 있고, TCP Keep-alive의 경우는 ‘Keep-alive 유지 시간’, ‘Keep-alive 패킷 재전송 시간(interval)’, ‘패킷 전송 빈도수’를 설정할 수 있다.

  • HTTP Keep-alive 설정
#cat /etc/httpd/conf/httpd.conf | grep -i  keepalive
KeepAlive On
KeepAliveTimeOut 60
  • TCP Keep-alive 설정
[root@localhost ~]# sysctl -a | grep keepalive
...(중략)
net.ipv4.tcp_keepalive_intvl = 75
net.ipv4.tcp_keepalive_probes = 9
net.ipv4.tcp_keepalive_time = 7200

그림으로 표현하자면 아래와 같다.

또 하나! HTTP Keep-alive와 TCP Keep-alive는 서로 다른 계층에서 동작하는만큼 동시에 활성화 될 수 있다. 이럴 경우 상위 레이어에 설정된 HTTP Keep-alive 옵션이 우선 시 된다. 즉, TCP Keep-alive에 어떤 수치가 설정된다고 해도 HTTP Keep-alive에 설정된 시간이 지나면 연결이 종료된다. (이 부분에 대한 설명은 아래 [참고사이트]의 ‘TCP 연결과 해제” 브런치에 잘 정리되어있다.)

LB와 timeout의 상관관계

이 부분도 [참고사이트]의 ‘TCP 연결과 해제” 브런치에 굉장히 잘 설명되어 있어서 내가 딱히 기술적으로 첨언을 할 필요는 없을 것 같다. (첨언할 정도의 실력이 안되는건 함정ㅋㅋㅋ)

대신 그때 헷갈렸던 부분을 다시 한번 되집자면…! ☝️

일단 아주 1차원적으로 말하자면 Idle timeout은 LB에 설정하는 옵션이고, Keep-alive는 EC2 인스턴스(서버)단에 설정하는 옵션이다. (여기서의 Keep-alive는 TCP Keep-alive)

위에 언급한 브런치에도 나와있듯이 LB의 세션테이블의 경우 무한한 자원이 아니기 때문에 Idle timeout이라는 옵션을 줘서 일정시간 동안 통신이 없으면 세션테이블에서 해당 연결을 지워버린다.

이러한 구조에서 Keep-alive 옵션이 활성화 되어있지 않으면 경우에 따라 연결을 계속 새롭게 맺어줘야하는 상황이 발생할 수 있다.

중요한건 이렇게 연결을 새로 맺을 때 서버의 리소스를 상당하게 잡아먹는다는 것인데, 그 말인 즉 Idle timeout에 의해 연결이 끊어지고 이를 다시 맺는 행위가 계속 반복되면 그 만큼 서버에 부담이 간다는 것이다.

이를 방지하고자 서버에 설정을 해주는게 바로 Keep-alive timeout이다. 한가지 중요한건 이 Keep-alive 시간이 LB에 설정된 Idle time보다 작아야 한다는건데 조금만 생각해보면 너무 당연한 말이라는걸 알 수 있다.

Keep-alive 시간이 Idle timeout 시간보다 크게 되면 keep-alive 패킷이 전송되기도 전에 LB의 Idle timeout에 의해 연결이 끊어지게 될 것이다. 그러면 너무 당연하게도 Keep-alive 설정 이유가 없어진다.

경우1) Keep -alive > Idle timeout

경우 2) Keep -alive < Idle timeout

사실 조금만 검색해봐도 너무 자세하고 친절하고 전문적인 설명이 많아서 내가 포스팅을 작성하는게 의미가 있나싶었지만 굳이 누가 보지 않더라도 내 스스로 정리한다는 차원에 내가 헷갈렸던 부분, 내가 알고 싶었던 부분만 아주 살짝 정리해보았다.

아직도 가야할 길이 먼 병아리 엔지니어이지만 언젠간 이 포스팅을 보며 가소롭게 웃을 그 날이 오기를 바라며 오늘의 포스팅은 여기까지 🍰

참고사이트

--

--

No responses yet