본문 바로가기
IT

[리눅스 기초 #89] 서버의 질서를 만드는 교통 정리: Nginx와 tc로 구현하는 트래픽 셰이핑(Traffic Shaping)

by sunyjiny 2026. 3. 19.
반응형

리눅스 기초 시리즈의 89번째 시간입니다! 지난 시간에는 Anycast IP와 GSLB를 통해 전 세계 사용자를 가장 가까운 서버로 안내하는 '글로벌 내비게이션'을 구축해 보았습니다. 이제 우리 인프라는 전 세계의 트래픽을 빨아들이는 거대한 블랙홀이 되었죠.

하지만 트래픽이 많이 온다고 무조건 좋은 것만은 아닙니다. 악의적인 공격자나 비정상적인 봇들이 고속도로를 점거해 버리면, 정작 중요한 실제 사용자들은 길 위에 갇혀버리게 됩니다. 오늘은 몰려드는 데이터의 파도 속에서 질서를 유지하고, 서비스의 가용성을 보장하는 트래픽 셰이핑(Traffic Shaping)속도 제한(Rate Limiting) 기법을 저의 경험담과 함께 정리해 보겠습니다.


1. 나의 경험담: "몰상식한 봇의 습격, 서버의 '체증'을 해결하다"

최근 제가 운영하는 유튜브 쇼츠 자동화 시스템의 API 서버에 비정상적인 호출이 쏟아진 적이 있었습니다. 특정 IP에서 초당 수백 번의 요청을 보내는 바람에 데이터베이스 커넥션이 바닥나고, 정상적인 영상 생성 작업들이 모두 'Pending' 상태에 빠졌죠. 당시 업무 스트레스로 위염이 도져 아연과 마그네슘을 챙겨 먹으며 간신히 버티던 상황이었는데, 서버까지 비명을 지르니 정말 눈앞이 캄캄했습니다.

이때 저를 구원한 것이 리눅스의 Traffic Control(tc)과 Nginx의 limit_req 모듈이었습니다. 영화 '하빈'의 전략가들이 적의 보급로를 차단해 승기를 잡듯, 저도 비정상적인 트래픽의 통로를 좁히고 질서를 잡았습니다. 폭주하던 요청들은 차분하게 줄을 서게 되었고, 서버의 CPU 온도는 평온을 되찾았습니다. 인프라 운영에서도 '절제'와 '규제'가 얼마나 중요한지 뼈저리게 느낀 순간이었습니다.


2. Before: "무방비 상태의 서버와 자원 고갈의 공포"

트래픽 제어 정책이 없는 서버는 문이 없는 대저택과 같습니다. 누구나 아무 때나 들어와서 냉장고를 비울 수 있죠. 특히 특정 사용자가 자원을 독점하면 나머지 사용자들은 응답 지연(Latency)을 겪거나 아예 접속조차 할 수 없게 됩니다.

과거의 무질서한 트래픽 상태 (Before):

Server Resource Exhaustion
 
# 특정 빌런 IP의 무차별 공격

tail -f access.log
1.2.3.4 - - [19/Mar/2026:10:00:01] "POST /api/generate" 200
1.2.3.4 - - [19/Mar/2026:10:00:01] "POST /api/generate" 200
... (초당 500회 반복)

결과: DB Connection Pool Full, 다른 사용자 접속 불가
"한 놈 때문에 동네 잔치가 다 망했네..."

(▲ Before: 상한선 없는 자유는 방종이 됩니다. 서비스의 공정성을 유지할 '규칙'이 전무한 상태였습니다.)


3. Action: Nginx와 리눅스 커널로 2중 방어선 구축하기

이제 애플리케이션 계층(L7)과 네트워크 계층(L3/L4)에서 동시에 트래픽을 제어하는 실전 코드를 살펴보겠습니다.

Step 1: Nginx에서 IP당 요청 횟수 제한 (L7)

특정 사용자가 API를 남용하지 못하도록 초당 5회로 제한하고, 순간적인 버스트는 10회까지 허용하는 설정입니다.

Nginx Config (nginx.conf)
 
http {
# 10MB 크기의 공유 메모리 영역 확보 (IP별 상태 저장)
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=5r/s;

server {
    location /api/ {
        # 버스트 10개까지 허용, 넘치면 503 에러 반환
        limit_req zone=mylimit burst=10 nodelay;
        proxy_pass http://my_backend;
    }
}
}

Step 2: 리눅스 tc(Traffic Control)로 대역폭 제한 (L3)

네트워크 인터페이스 레벨에서 전송 속도를 강제로 제한하여 물리적인 자원 독점을 방지합니다.

Bash Terminal (tc command)
 
# eth0 인터페이스의 나가는 속도를 10mbit로 제한 (TBF 알고리즘)
sudo tc qdisc add dev eth0 root tbf rate 10mbit burst 32kbit latency 400ms

설정 확인
tc qdisc show dev eth0

설정 삭제 (원상복구)
sudo tc qdisc del dev eth0 root

(▲ Action: Nginx는 '요청의 개수'를 관리하고, tc는 '데이터의 속도'를 관리합니다. 이 2중 방어선이 구축되면 어떤 트래픽 폭주가 와도 핵심 서비스는 보호받게 됩니다.)


4. After: "폭풍우 속에서도 흔들리지 않는 편안함"

트래픽 제어 정책을 적용한 뒤, 제 인프라는 '예측 가능한 안정성'을 확보했습니다.

가져온 혁신적인 변화들:

  • 서비스 가용성 극대화: 비정상적인 트래픽을 입구에서 차단하므로, 데이터베이스나 백엔드 서버가 과부하로 뻗는 일이 사라졌습니다.
  • 사용자 경험(UX) 개선: 모든 사용자가 공평하게 자원을 분배받으므로, 평균 응답 속도가 일정하게 유지됩니다.
  • 비용 최적화: 불필요한 트래픽 전송을 막아 클라우드 네트워크 비용(Egress Cost)을 효과적으로 절감했습니다.

5. Rate Limiting vs Traffic Shaping 비교

항목 Rate Limiting (속도 제한) Traffic Shaping (트래픽 셰이핑)
주요 목적 요청 횟수 제어 및 남용 방지 데이터 전송률 평활화 및 지연 제어
동작 방식 한도 초과 시 즉시 거부 (Drop) 초과분을 큐에 넣어 지연 전송 (Queue)
적용 계층 주로 L7 (Application) 주로 L3 (Network/Kernel)
비유 입장 인원 제한 (클럽 입구) 차선 제한 및 가변 속도제 (고속도로)

6. 마치며: 질서 있는 서버가 평화를 가져옵니다.

리눅스 기초 89단계를 거치며 우리는 이제 단순히 트래픽을 받아내는 것을 넘어, 그 흐름을 지배하는 법을 배웠습니다. 셰이핑과 레이트 리미팅은 대규모 서비스 운영에서 '품격'을 결정짓는 기술입니다. 몰려드는 데이터에 휘둘리지 말고, 여러분의 의지대로 인프라의 질서를 설계해 보세요.

오늘의 인사이트: "훌륭한 엔지니어는 모든 문을 열어두는 사람이 아니라, 누구에게 언제 문을 열어줄지 결정하는 사람이다."


89번째 이야기를 마칩니다. 이제 우리 인프라는 어떤 폭풍우에도 질서를 잃지 않습니다. 다음 시간에는 웹 애플리케이션을 타겟으로 한 지능형 공격을 막아내는 최후의 방패, '클라우드 네이티브 보안의 정점: WAF(Web Application Firewall)와 Cloud Armor 운영 전략'에 대해 다뤄보겠습니다.

이 글이 여러분의 서버 '교통 체증'을 해결하는 데 도움이 되었나요? 혹시 Nginx 설정 중 nodelay 옵션의 유무에 따른 차이가 궁금하신가요?

Nginx의 Leaky Bucket 알고리즘 작동 원리를 시각적으로 이해할 수 있는 추가 가이드를 준비해 드릴까요?

반응형