본문 바로가기

리눅스

Backlog(백로그)란?

반응형

Backlog(백로그)란?

Backlog(백로그)란, 서버가 동시에 몰려드는 접속 요청을 처리하기 위해 사용하는 연결 대기열(Queue) 입니다.

즉, 서버가 즉시 처리하지 못한 TCP 연결 요청을 잠시 보관해 두는 공간입니다.

 

클라이언트가 서버에 연결을 시도하면 TCP 3-Way Handshake 과정을 거치게 되는데 서버가 바쁘거나 애플리케이션이 아직 accept() 하지 못한 경우 이 연결 요청들은 백로그 큐에 대기하게 됩니다.

TCP 연결과 Backlog의 역할

TCP 3-Way Handshake

TCP 연결은 다음 순서로 진행됩니다.

  1. 클라이언트 → 서버 : SYN
  2. 서버 → 클라이언트 : SYN-ACK
  3. 클라이언트 → 서버 : ACK

서버는 이 과정에서 모든 연결을 즉시 애플리케이션에 전달하지 않고 상태에 따라 두 개의 내부 큐로 나누어 관리합니다.

두 가지 종류의 Backlog Queue

리눅스 커널은 내부적으로 두 개의 큐(Queue)를 사용합니다.

SYN Queue (Incomplete Connection Queue)

클라이언트가 SYN을 보내고 서버가 SYN-ACK을 보낸 뒤 아직 ACK을 받지 못한 '반쯤 열린' 상태의 연결들이 머무는 곳입니다.

  • 관련 커널 파라미터 : net.ipv4.tcp_max_syn_backlog

Accept Queue (Completed Connection Queue)

3-Way Handshake가 완전히 끝나서 연결이 수립(ESTABLISHED)되었으나 애플리케이션(Nginx, DB 등)이 아직 가져가지 않은 연결들이 머무는 곳입니다.

  • listen() 시 설정하는 backlog 값이 주로 이 큐의 크기에 영향을 줍니다.

Backlog 크기를 결정하는 요소

백로그의 크기는 단순히 한 곳에서 정해지는 것이 아니라 애플리케이션 설정과 운영체제 설정 중 더 작은 값으로 결정됩니다.

  • 애플리케이션 설정 : Nginx의 listen 80 backlog=511;이나 Apache의 ListenBacklog 설정값
  • OS 커널 설정 : 시스템 전체의 제한 값인 net.core.somaxconn

만약 Nginx에서 1024를 설정했더라도 OS 커널의 somaxconn이 128이라면 실제 백로그는 128로 작동합니다.

Backlog가 가득 차면(Full) 어떤 일이 발생할까?

서버가 감당할 수 없을 정도로 요청이 쏟아져서 대기 줄(Backlog)이 꽉 차면 다음과 같은 현상이 발생합니다.

  • 연결 거부: 클라이언트는 Connection Refused 에러를 받게 됩니다.
  • 패킷 드랍: 서버가 응답을 하지 않고 패킷을 무시하여 클라이언트 측에서 Timeout이 발생합니다.
  • 성능 저하: 대기열이 길어질수록 사용자가 체감하는 응답 시간(Latency)이 늘어납니다.
728x90

Backlog 상태 확인

실시간 확인 (ss 명령어)

ss -ltn sport = :6379
State               Recv-Q              Send-Q                           Local Address:Port                           Peer Address:Port             Process              
LISTEN              0                   511                                    0.0.0.0:6379                                0.0.0.0:*
  • Recv-Q: 현재 Accept Queue에서 대기 중인 연결 수
  • Send-Q: 설정된 최대 백로그 크기

판단 기준 : 만약 Recv-Q가 Send-Q와 같거나 거의 근접해 있다면, 백로그가 꽉 차서 새로운 접속 요청을 처리하지 못하고 있는 위험한 상태입니다.

 

커널 누적 통계 확인 (netstat)

실시간으로 계속 들여다볼 수 없기 때문에 과거에 백로그가 꽉 차서 패킷을 버린 기록이 있는지 확인하는 것이 더 정확합니다.

netstat -s | grep -i "listen"
    23 SYNs to LISTEN sockets dropped

또는

nstat -az TcpExtListenDrops
#kernel
TcpExtListenDrops               23                 0.0

출력 결과에서 다음과 같은 항목의 숫자가 0보다 크거나 계속 증가하고 있다면 백로그가 부족한 것입니다.

  • SYNs to LISTEN sockets dropped: SYN Queue가 꽉 차서 요청을 버림.
  • times the listen queue of a socket overflowed: Accept Queue가 꽉 차서 연결을 버림.

커널 로그 확인 (dmesg)

백로그가 심각하게 부족하여 커널 수준에서 문제가 되면 시스템 로그에 기록되기도 합니다.

dmesg | grep -i "Possible SYN flooding"
TCP: request_sock_TCP: Possible SYN flooding on port ...

운영체제 Backlog 설정 변경

즉시 적용

sysctl -w net.core.somaxconn=4096

영구 적용

sudo vim /etc/sysctl.conf
net.core.somaxconn=65535
net.ipv4.tcp_max_syn_backlog=8192
sudo sysctl -p

Redis Backlog 설정 변경

런타임 변경

redis-cli -p 6381
> CONFIG SET tcp-backlog 4096

설정 파일 변경

sudo vim /etc/redis/6381.conf
tcp-backlog 4096
sudo systemctl restart redis-server

 

 

728x90
반응형