Ver3.5 리버스 프록시와 캐시 서버 완전 정복

리버스 프록시와 캐시 서버 완전 정복
Varnish & Squid로 서버 성능을 10배 끌어올리는 실전 가이드 ⚡
야, 솔직히 말해봐. 🤔
서버 응답이 느려서 사용자들이 이탈하는 거 경험해봤지? 트래픽 폭탄 맞고 서버가 뻗어버린 적 있지?
그 해결책이 바로 리버스 프록시와 캐시 서버야. 오늘은 이 두 개념을 완전히 씹어먹어 보자고!
🤔 리버스 프록시가 뭔데?
먼저 프록시(Proxy)라는 단어 자체가 "대리인"이라는 뜻이야.
우리가 흔히 아는 포워드 프록시(Forward Proxy)는 클라이언트 앞에 서서 클라이언트를 대신해서 인터넷에 요청을 보내는 녀석이야. 회사 방화벽이나 VPN 같은 거 생각하면 돼.
근데 리버스 프록시(Reverse Proxy)는 반대야! 🔄
서버 앞에 서서 클라이언트의 요청을 대신 받아주는 역할을 해. 클라이언트 입장에서는 리버스 프록시가 진짜 서버처럼 보이는 거지. 뒤에 실제 백엔드 서버들이 몇 개가 있는지, 어떤 기술 스택인지 전혀 모르는 거야.
리버스 프록시는 마치 호텔 프런트 데스크 같아.
손님(클라이언트)은 프런트에만 얘기하면 되고, 프런트가 알아서 청소부, 룸서비스, 주방 등(백엔드 서버들)에 일을 분배하는 거야. 손님은 뒤에서 어떻게 돌아가는지 알 필요가 없지!
리버스 프록시가 해주는 일들을 정리해보면:
⚡ 캐시 서버의 마법
캐시 서버의 핵심 원리는 간단해. "한 번 만든 거 다시 만들지 말자!" 🎯
동일한 요청이 들어올 때마다 백엔드 서버에서 DB 조회하고, 로직 처리하고, 응답 생성하는 게 얼마나 비효율적인지 생각해봐.
예를 들어 뉴스 사이트의 메인 페이지를 생각해봐.
1초에 1,000명이 접속한다면? 매번 DB에서 최신 뉴스 목록을 가져오는 쿼리를 1,000번 실행하는 거야. 근데 뉴스가 1초마다 바뀌지는 않잖아? 그럼 캐시에 저장해두고 1,000명 모두에게 저장된 응답을 돌려주면 DB 쿼리는 딱 1번만 실행되는 거지!
캐시 히트율이 90%라는 건 100개의 요청 중 90개는 백엔드 서버를 거치지 않는다는 뜻이야. 서버 부하가 10분의 1로 줄어드는 거지!
🎯 Varnish Cache — 웹 가속기의 왕
자, 이제 본격적으로 Varnish Cache를 파헤쳐보자! 🕵️
Varnish는 2006년 노르웨이의 Poul-Henning Kamp가 개발한 오픈소스 HTTP 가속기야. "웹 가속기(Web Accelerator)"라고도 불리는데, 그 이유가 있어.
Varnish의 가장 큰 특징은 VCL(Varnish Configuration Language)이라는 자체 설정 언어를 사용한다는 거야. 처음엔 좀 낯설 수 있는데, 익숙해지면 엄청 강력해!
HTTP 전용 최적화 메모리 기반 초고속 VCL 유연한 설정 ESI 지원 Grace Mode
Varnish는 HTTP 트래픽만을 위해 설계된 특화 솔루션이야. 범용 프록시가 아니라 HTTP 캐싱에 모든 걸 쏟아부은 녀석이지.
📝 Varnish 기본 설치 및 설정
Ubuntu/Debian 기준으로 설치해보자:
# Varnish 설치 (Ubuntu 22.04 기준)
sudo apt-get update
sudo apt-get install varnish
# 버전 확인
varnishd -V
# 서비스 시작
sudo systemctl start varnish
sudo systemctl enable varnish
기본 설정 파일은 /etc/varnish/default.vcl에 있어. 이게 바로 VCL 파일이야!
# /etc/varnish/default.vcl 기본 구조
vcl 4.1;
# 백엔드 서버 정의
backend default {
.host = "127.0.0.1"; # 백엔드 서버 IP
.port = "8080"; # 백엔드 서버 포트
.connect_timeout = 5s;
.first_byte_timeout = 30s;
.between_bytes_timeout = 60s;
}
# 요청 수신 시 처리 로직
sub vcl_recv {
# 쿠키가 있는 요청은 캐시하지 않음 (기본 동작)
if (req.http.Cookie) {
return (pass);
}
# POST 요청은 캐시하지 않음
if (req.method == "POST") {
return (pass);
}
return (hash); # 캐시 조회
}
# 백엔드 응답 처리
sub vcl_backend_response {
# 캐시 TTL 설정 (1시간)
set beresp.ttl = 1h;
# 압축 활성화
set beresp.do_gzip = true;
}
# 캐시 히트 시 처리
sub vcl_hit {
return (deliver);
}
# 캐시 미스 시 처리
sub vcl_miss {
return (fetch); # 백엔드에서 가져옴
}
# 응답 전달 시 처리
sub vcl_deliver {
# 캐시 히트/미스 헤더 추가 (디버깅용)
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
return (deliver);
}
🔥 VCL의 핵심 — 요청 흐름 이해하기
Varnish의 요청 처리 흐름을 이해하는 게 핵심이야. VCL에는 여러 개의 서브루틴(subroutine)이 있고, 각 단계에서 요청을 어떻게 처리할지 결정해:
🔄 Varnish 요청 처리 흐름
💎 Varnish 고급 기능들
1. Grace Mode — 서버가 죽어도 캐시는 살아있어!
# Grace Mode 설정
# 백엔드가 다운되어도 오래된 캐시를 일정 시간 제공
sub vcl_backend_response {
set beresp.ttl = 10m; # 정상 캐시 유효시간: 10분
set beresp.grace = 1h; # 백엔드 장애 시 1시간 더 제공
}
sub vcl_recv {
set req.grace = 30s; # 30초 동안 오래된 캐시 허용
}
Grace Mode는 진짜 꿀 기능이야! 🍯 백엔드 서버가 잠깐 다운되거나 응답이 느릴 때, 만료된 캐시라도 사용자에게 제공해서 서비스 중단을 막아줘. 사용자 입장에서는 서버 장애를 눈치채지 못하는 거지!
2. ESI(Edge Side Includes) — 페이지 조각 캐싱
# ESI 활성화
sub vcl_backend_response {
if (beresp.http.content-type ~ "text/html") {
set beresp.do_esi = true; # ESI 처리 활성화
}
}
# HTML 파일에서 ESI 태그 사용 예시
# <esi:include src="/header" /> ← 헤더 부분만 별도 캐시
# <esi:include src="/sidebar" /> ← 사이드바 별도 캐시
# <p>사용자별 개인화 콘텐츠는 ESI 밖에</p>
ESI는 페이지를 여러 조각으로 나눠서 각각 다른 TTL로 캐시할 수 있게 해줘. 예를 들어 헤더는 1시간, 뉴스 목록은 5분, 사용자 정보는 캐시 안 함 — 이런 식으로 세밀하게 제어 가능!
3. 다중 백엔드 & 로드 밸런싱
import directors; # directors VMOD 임포트
backend server1 {
.host = "192.168.1.10";
.port = "8080";
.weight = 2; # 가중치 2 (더 많은 트래픽 처리)
}
backend server2 {
.host = "192.168.1.11";
.port = "8080";
.weight = 1;
}
backend server3 {
.host = "192.168.1.12";
.port = "8080";
.weight = 1;
}
sub vcl_init {
# 라운드 로빈 로드 밸런서 생성
new lb = directors.round_robin();
lb.add_backend(server1);
lb.add_backend(server2);
lb.add_backend(server3);
# 또는 랜덤 방식
# new lb = directors.random();
# lb.add_backend(server1, 2.0); # 가중치 2.0
}
sub vcl_recv {
set req.backend_hint = lb.backend();
}
🔧 Varnish 모니터링 도구
Varnish는 강력한 내장 모니터링 도구를 제공해:
# 실시간 통계 확인
varnishstat
# 실시간 로그 스트리밍
varnishlog
# 캐시 히트율 확인
varnishstat -1 -f MAIN.cache_hit,MAIN.cache_miss
# 특정 URL 캐시 무효화 (Purge)
varnishadm "ban req.url ~ /news"
# 특정 오브젝트 즉시 삭제
curl -X PURGE http://localhost/path/to/resource
1. HTTPS 직접 처리 불가 — Varnish 자체는 SSL/TLS를 처리 못해. Nginx나 HAProxy를 앞에 두고 SSL 종료 후 Varnish로 넘겨야 해.
2. 기본적으로 쿠키가 있으면 캐시 안 함 — 로그인 사용자 요청은 기본적으로 캐시를 건너뛰어. VCL에서 명시적으로 설정해야 해.
3. 재시작 시 캐시 초기화 — Varnish를 재시작하면 메모리 캐시가 모두 날아가. 이를 방지하려면 Persistent Storage 설정 필요.
🦑 Squid Cache — 범용 프록시의 강자
이번엔 Squid를 알아보자! Squid는 1996년부터 시작된 오래된 오픈소스 프록시 서버야. 역사가 길다 보니 안정성이 검증되어 있고, 전 세계 수많은 기업과 ISP에서 사용 중이야.
Squid의 가장 큰 차별점은 범용성이야. Varnish가 HTTP 전용 스포츠카라면, Squid는 뭐든 다 실을 수 있는 트럭 같은 존재야! 🚛
HTTP 전용, 메모리 캐시
초고속, VCL 설정
웹 가속에 특화
HTTP/FTP/HTTPS 등 다양
디스크 캐시, ACL 강력
포워드+리버스 모두 가능
📝 Squid 설치 및 기본 설정
# Squid 설치
sudo apt-get update
sudo apt-get install squid
# 설정 파일 위치
# /etc/squid/squid.conf
# 서비스 시작
sudo systemctl start squid
sudo systemctl enable squid
# 설정 파일 문법 검사
sudo squid -k parse
Squid의 설정 파일은 squid.conf야. Varnish의 VCL보다는 좀 더 직관적인 키-값 형태야:
# /etc/squid/squid.conf 핵심 설정
# 포트 설정 (기본 3128)
http_port 3128
# 리버스 프록시 모드 설정
http_port 80 accel vhost defaultsite=example.com
# 백엔드 서버 정의
cache_peer 192.168.1.10 parent 8080 0 no-query originserver name=myapp
# ACL 정의
acl localnet src 192.168.0.0/16 # 내부 네트워크
acl SSL_ports port 443
acl Safe_ports port 80 443 8080
acl CONNECT method CONNECT
# 접근 제어
http_access allow localnet
http_access allow localhost
http_access deny all
# 캐시 디렉토리 설정 (디스크 캐시)
# 형식: cache_dir [타입] [경로] [크기MB] [1단계 디렉토리수] [2단계 디렉토리수]
cache_dir ufs /var/spool/squid 10000 16 256
# 10GB 캐시, 16개 1단계 디렉토리, 256개 2단계 디렉토리
# 메모리 캐시 크기
cache_mem 512 MB
# 최대 오브젝트 크기
maximum_object_size 100 MB
maximum_object_size_in_memory 8 MB
# 로그 설정
access_log /var/log/squid/access.log squid
cache_log /var/log/squid/cache.log
# 워커 프로세스 수 (CPU 코어 수에 맞게)
workers 4
🔐 Squid ACL — 강력한 접근 제어
Squid의 ACL(Access Control List)은 정말 강력해. 다양한 기준으로 트래픽을 제어할 수 있어:
# 다양한 ACL 타입 예시
# IP 기반 ACL
acl office_network src 10.0.0.0/8
acl blocked_ips src "/etc/squid/blocked_ips.txt"
# 도메인 기반 ACL
acl social_media dstdomain .facebook.com .twitter.com .instagram.com
acl allowed_sites dstdomain "/etc/squid/allowed_sites.txt"
# 시간 기반 ACL
acl work_hours time MTWHF 09:00-18:00
acl lunch_break time MTWHF 12:00-13:00
# URL 패턴 ACL
acl streaming_urls url_regex -i youtube netflix
# 파일 타입 ACL
acl media_files urlpath_regex -i \.(mp4|avi|mkv|mov)$
# 접근 제어 규칙 적용
http_access deny social_media work_hours # 업무시간 SNS 차단
http_access allow social_media lunch_break # 점심시간 SNS 허용
http_access deny streaming_urls # 스트리밍 차단
http_access allow office_network # 사무실 네트워크 허용
http_access deny all # 나머지 모두 차단
기업 환경에서 Squid를 쓰는 가장 큰 이유 중 하나가 바로 이 ACL이야. 업무 시간에 SNS 차단, 특정 사이트만 허용, 대용량 파일 다운로드 제한 등 세밀한 인터넷 정책을 구현할 수 있거든. IT 관리자들의 필수 도구!
🗄️ Squid 캐시 스토리지 전략
Squid는 여러 가지 캐시 스토리지 타입을 지원해:
# 1. UFS (Unix File System) - 가장 기본적인 방식
cache_dir ufs /var/spool/squid 10000 16 256
# 2. AUFS (Async UFS) - 비동기 I/O로 성능 향상
cache_dir aufs /var/spool/squid 10000 16 256
# 3. COSS (Cyclic Object Storage System) - 순환 저장
cache_dir coss /var/spool/squid/coss 2000 max-size=65536
# 4. Rock - SSD에 최적화된 고성능 스토리지
cache_dir rock /var/spool/squid/rock 5000 \
slot-size=32768 max-size=32768
# 여러 캐시 디렉토리 조합 (SSD + HDD)
cache_dir rock /ssd/squid 2000 slot-size=32768 # SSD: 빠른 접근
cache_dir aufs /hdd/squid 50000 16 256 # HDD: 대용량
# 캐시 교체 정책
cache_replacement_policy heap LFUDA # Least Frequently Used with Dynamic Aging
# 또는
cache_replacement_policy heap GDSF # Greedy Dual Size Frequency
🔍 Squid 투명 프록시 설정
투명 프록시(Transparent Proxy)는 클라이언트가 프록시 설정을 하지 않아도 자동으로 트래픽이 Squid를 통과하게 만드는 방식이야. 기업 네트워크에서 많이 써:
# 투명 프록시 설정
http_port 3128 intercept # intercept 모드
# iptables로 트래픽 리다이렉트 (Linux)
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp \
--dport 80 -j REDIRECT --to-port 3128
# IPv6도 처리
sudo ip6tables -t nat -A PREROUTING -i eth0 -p tcp \
--dport 80 -j REDIRECT --to-port 3128
# HTTPS 투명 프록시 (SSL Bump)
https_port 3129 intercept ssl-bump \
cert=/etc/squid/ssl_cert/myCA.pem \
key=/etc/squid/ssl_cert/myCA.key
ssl_bump server-first all
🏗️ 실전 아키텍처 구성
자, 이제 실제로 어떻게 조합해서 쓰는지 알아보자! 위 SVG에서 보여준 것처럼 Nginx + Varnish + App Server 조합이 가장 일반적인 고성능 웹 서버 구성이야.
🔧 Nginx + Varnish 연동 설정
Nginx가 80/443 포트를 받아서 SSL 처리 후 Varnish(6081 포트)로 넘기고, Varnish가 캐시 처리 후 백엔드 앱 서버로 전달하는 구조야:
# /etc/nginx/sites-available/example.com
server {
listen 443 ssl http2;
server_name example.com www.example.com;
# SSL 설정
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
# Varnish로 프록시 (HTTP로 전달)
location / {
proxy_pass http://127.0.0.1:6081; # Varnish 포트
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 타임아웃 설정
proxy_connect_timeout 5s;
proxy_read_timeout 30s;
}
# 정적 파일은 Nginx에서 직접 서빙 (Varnish 우회)
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2)$ {
root /var/www/example.com/public;
expires 30d;
add_header Cache-Control "public, immutable";
}
}
# HTTP → HTTPS 리다이렉트
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
# /etc/varnish/default.vcl - Nginx와 연동
vcl 4.1;
backend app1 {
.host = "127.0.0.1";
.port = "8001";
.probe = {
.url = "/health";
.timeout = 2s;
.interval = 5s;
.window = 5;
.threshold = 3;
}
}
backend app2 {
.host = "127.0.0.1";
.port = "8002";
.probe = {
.url = "/health";
.timeout = 2s;
.interval = 5s;
.window = 5;
.threshold = 3;
}
}
import directors;
sub vcl_init {
new cluster = directors.round_robin();
cluster.add_backend(app1);
cluster.add_backend(app2);
}
sub vcl_recv {
set req.backend_hint = cluster.backend();
# X-Forwarded-For 헤더 처리
if (req.http.X-Forwarded-For) {
set req.http.X-Real-IP = req.http.X-Forwarded-For;
}
# 정적 파일 캐시 (쿠키 무시)
if (req.url ~ "\.(jpg|jpeg|png|gif|ico|css|js|woff2)(\?.*)?$") {
unset req.http.Cookie;
return (hash);
}
# 로그인 사용자 캐시 처리
if (req.http.Cookie ~ "session_id") {
return (pass); # 로그인 사용자는 캐시 우회
}
# PURGE 요청 처리 (캐시 무효화)
if (req.method == "PURGE") {
if (req.http.X-Purge-Token != "your-secret-token") {
return (synth(403, "Forbidden"));
}
return (purge);
}
return (hash);
}
sub vcl_hash {
hash_data(req.url);
# 모바일/데스크톱 별도 캐시
if (req.http.User-Agent ~ "Mobile|Android|iPhone") {
hash_data("mobile");
} else {
hash_data("desktop");
}
hash_data(req.http.host);
return (lookup);
}
sub vcl_backend_response {
# 404, 500 에러는 짧게 캐시
if (beresp.status == 404) {
set beresp.ttl = 30s;
} else if (beresp.status >= 500) {
set beresp.ttl = 0s;
set beresp.uncacheable = true;
} else {
set beresp.ttl = 10m; # 기본 10분 캐시
set beresp.grace = 1h; # Grace 1시간
}
# 정적 파일은 더 오래 캐시
if (bereq.url ~ "\.(jpg|jpeg|png|gif|ico|css|js)$") {
set beresp.ttl = 24h;
}
return (deliver);
}
sub vcl_deliver {
# 디버깅 헤더 추가
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
set resp.http.X-Cache-Hits = obj.hits;
} else {
set resp.http.X-Cache = "MISS";
}
# 불필요한 헤더 제거
unset resp.http.X-Powered-By;
unset resp.http.Server;
return (deliver);
}
🔄 캐시 무효화(Cache Invalidation) 전략
캐시의 가장 어려운 문제 중 하나가 바로 캐시 무효화야. 데이터가 업데이트됐을 때 오래된 캐시를 어떻게 처리할 것인가!
"컴퓨터 과학에서 어려운 문제는 딱 두 가지다. 캐시 무효화와 이름 짓기."
— Phil Karlton
그만큼 캐시 무효화는 까다로운 문제야. 전략을 잘 세워야 해!
# 1. TTL 기반 자동 만료 (가장 단순)
set beresp.ttl = 5m; # 5분 후 자동 만료
# 2. PURGE 요청으로 즉시 삭제
# Varnish에 PURGE 요청 보내기
curl -X PURGE -H "X-Purge-Token: your-secret-token" \
http://localhost:6081/news/article/123
# 3. BAN을 이용한 패턴 기반 무효화
# 특정 패턴의 URL 모두 무효화
varnishadm "ban req.url ~ ^/news/"
varnishadm "ban req.http.host == example.com && req.url ~ /product/"
# 4. 태그 기반 무효화 (Surrogate-Key / Cache-Tag)
# 백엔드에서 응답 헤더에 태그 추가
# Response Header: Surrogate-Key: product-123 category-electronics
sub vcl_backend_response {
# 태그 헤더를 Xkey로 저장
if (beresp.http.Surrogate-Key) {
set beresp.http.xkey = beresp.http.Surrogate-Key;
}
}
# 특정 태그의 캐시 모두 무효화
varnishadm "xkey.purge product-123"
📊 성능 벤치마크 & 튜닝
실제로 얼마나 빨라지는지 궁금하지? 🤩 실제 벤치마크 결과들을 보면 놀라울 거야!
평균 응답속도 향상
부하 감소
처리 요청 수
🔧 Varnish 성능 튜닝 핵심 파라미터
# /etc/varnish/varnish.params 또는 systemd 서비스 파일
# 메모리 캐시 크기 (RAM의 50-70% 권장)
VARNISH_STORAGE="malloc,4G" # 4GB 메모리 캐시
# 또는 파일 기반 스토리지 (대용량)
VARNISH_STORAGE="file,/var/lib/varnish/varnish_storage.bin,20G"
# 워커 스레드 설정
VARNISH_NCSA_LOG=1
# varnishd 직접 실행 시 파라미터
varnishd \
-a 0.0.0.0:6081 \ # 리스닝 포트
-T localhost:6082 \ # 관리 포트
-f /etc/varnish/default.vcl \
-s malloc,4G \ # 4GB 메모리 캐시
-p thread_pools=2 \ # CPU 코어 수에 맞게
-p thread_pool_min=100 \ # 최소 스레드 수
-p thread_pool_max=5000 \ # 최대 스레드 수
-p thread_pool_add_delay=2ms \
-p connect_timeout=5s \
-p first_byte_timeout=30s \
-p between_bytes_timeout=60s \
-p workspace_backend=256k \ # 백엔드 워크스페이스
-p workspace_client=256k # 클라이언트 워크스페이스
🔧 Squid 성능 튜닝
# /etc/squid/squid.conf 성능 튜닝
# 메모리 설정
cache_mem 1024 MB # 메모리 캐시 1GB
memory_replacement_policy heap GDSF # 메모리 교체 정책
# 디스크 캐시 최적화
cache_dir aufs /var/spool/squid 20000 16 256 # 20GB
cache_replacement_policy heap LFUDA # 디스크 교체 정책
# 연결 설정
max_filedescriptors 65536 # 최대 파일 디스크립터
client_persistent_connections on
server_persistent_connections on
# 요청 처리 최적화
pipeline_prefetch 1 # 파이프라인 프리페치
collapsed_forwarding on # 동일 요청 병합 (캐시 스탬피드 방지)
# DNS 캐싱
dns_nameservers 8.8.8.8 8.8.4.4
positive_dns_ttl 6 hours
negative_dns_ttl 1 minute
# 로그 최적화 (성능 중요 시 로그 최소화)
access_log none
cache_log /var/log/squid/cache.log
cache_store_log none
# 워커 프로세스 (멀티코어 활용)
workers 8 # CPU 코어 수에 맞게
🛠️ 실전 트러블슈팅
실제로 운영하다 보면 이런 문제들을 자주 만나게 돼. 미리 알아두면 당황하지 않을 수 있어! 😎
원인들:
• Set-Cookie 헤더가 응답에 포함되어 있음
• Cache-Control: no-cache, no-store 헤더
• Authorization 헤더가 요청에 포함됨
• POST/PUT/DELETE 메서드 요청
해결:
# Varnish에서 불필요한 Set-Cookie 제거
sub vcl_backend_response {
# 정적 파일의 Set-Cookie 헤더 제거
if (bereq.url ~ "\.(jpg|png|css|js)$") {
unset beresp.http.Set-Cookie;
}
# Cache-Control 헤더 강제 설정
if (beresp.http.Cache-Control ~ "no-cache") {
unset beresp.http.Cache-Control;
set beresp.ttl = 5m;
}
}
# 요청에서 불필요한 쿠키 제거
sub vcl_recv {
# 트래킹 쿠키 제거 (캐시 히트율 향상)
set req.http.Cookie = regsuball(req.http.Cookie,
"(^|;\s*)(_ga|_gid|_fbp|__utm[a-z]+)=[^;]*", "");
# 쿠키가 비어있으면 헤더 제거
if (req.http.Cookie ~ "^\s*$") {
unset req.http.Cookie;
}
}
캐시가 만료되는 순간 수천 개의 요청이 동시에 백엔드로 쏟아지는 현상이야. 서버가 순간적으로 과부하 상태가 되지.
# Varnish에서 캐시 스탬피드 방지
sub vcl_recv {
# 캐시 만료 전에 미리 갱신 (Saint Mode)
set req.grace = 30s; # 30초 동안 오래된 캐시 허용
}
sub vcl_backend_response {
set beresp.ttl = 10m;
set beresp.grace = 1h; # 1시간 Grace 기간
# 백그라운드 갱신 활성화
set beresp.keep = 8h; # 8시간 동안 백그라운드 갱신 가능
}
# Squid에서 캐시 스탬피드 방지
# squid.conf
collapsed_forwarding on # 동일 URL 요청 병합
# 동일한 캐시 미스 요청이 여러 개 들어오면 하나만 백엔드로 전달
Varnish가 메모리를 너무 많이 사용해서 시스템이 OOM Killer에 의해 프로세스를 죽이는 경우야.
# 메모리 사용량 모니터링
varnishstat -1 -f MAIN.n_object,MAIN.n_expired,SMA.s0.g_bytes
# 메모리 제한 설정
# /etc/systemd/system/varnish.service
[Service]
MemoryLimit=6G # 최대 6GB 메모리 사용 제한
# 오브젝트 크기 제한
# VCL에서 큰 오브젝트 캐시 제외
sub vcl_backend_response {
# 10MB 이상 오브젝트는 캐시하지 않음
if (beresp.http.Content-Length ~ "[0-9]{8,}") {
set beresp.uncacheable = true;
set beresp.ttl = 120s;
}
}
🎯 언제 뭘 써야 할까?
자, 이제 Varnish와 Squid를 모두 알았으니 어떤 상황에서 뭘 선택해야 하는지 정리해보자!
고트래픽 웹사이트 미디어/뉴스 서비스 API 게이트웨이 CDN 구성
• 초당 수만~수십만 HTTP 요청을 처리해야 할 때
• 세밀한 캐시 제어 로직이 필요할 때 (VCL 활용)
• 웹 콘텐츠 가속이 주 목적일 때
• ESI로 페이지 조각 캐싱이 필요할 때
• 메모리가 충분하고 디스크 캐시가 필요 없을 때
기업 네트워크 ISP 프록시 콘텐츠 필터링 대용량 파일 캐싱
• HTTP 외 FTP, HTTPS 투명 프록시가 필요할 때
• 강력한 ACL 기반 접근 제어가 필요할 때
• 대용량 파일(이미지, 동영상)을 디스크에 캐시할 때
• 포워드 프록시 + 리버스 프록시 모두 필요할 때
• 기업 인터넷 게이트웨이로 사용할 때
대형 미디어 회사나 CDN 업체에서는 두 가지를 함께 쓰기도 해.
예를 들어 Squid를 포워드 프록시로 내부 직원들의 인터넷 접근 제어에 쓰고,
Varnish를 리버스 프록시로 외부 사용자들에게 서비스를 제공하는 식으로!
🌐 실제 서비스 적용 사례
이론은 충분히 알았으니, 실제로 어떤 서비스들이 이걸 쓰는지 알아보자!
재능넷처럼 다양한 재능을 거래하는 플랫폼에서도 리버스 프록시와 캐시 서버는 필수야. 재능 목록 페이지, 인기 재능 카테고리, 검색 결과 등 자주 조회되는 콘텐츠를 Varnish로 캐시하면 서버 부하를 크게 줄이고 사용자 경험을 향상시킬 수 있어. 특히 트래픽이 몰리는 이벤트 기간에 진가를 발휘하지!
🔮 최신 트렌드 & 대안들
Varnish와 Squid 외에도 최근에는 다양한 대안들이 등장했어. 알아두면 좋아!
proxy_cache 모듈로 기본적인 캐싱 가능. 이미 Nginx를 쓰고 있다면 별도 서버 없이 캐시 추가 가능. 단, Varnish보다는 기능이 제한적.
애플리케이션 레벨 캐시. HTTP 레이어가 아닌 코드 레벨에서 캐시. DB 쿼리 결과, 세션 등을 캐시하는 데 특화.
클라우드 기반 CDN/캐시. 인프라 관리 없이 글로벌 캐시 가능. 비용이 발생하지만 운영 부담이 적음.
쿠버네티스 환경에 특화된 현대적 리버스 프록시. 자동 서비스 디스커버리, Let's Encrypt 자동 갱신 등 DevOps 친화적.
소규모 서비스: Nginx (캐시 기능 내장) + Redis
중규모 서비스: Nginx (SSL) + Varnish (캐시) + App Server
대규모 서비스: Cloudflare/CDN + Nginx + Varnish + App Cluster + Redis
기업 내부망: Squid (포워드 프록시 + 필터링)
쿠버네티스: Traefik/Nginx Ingress + Redis
📝 마무리 정리
자, 오늘 엄청 많은 내용을 다뤘는데 핵심만 다시 정리해볼게! 🎯
• Varnish 공식 문서: varnish-cache.org/docs
• Squid 공식 문서: squid-cache.org/Doc
• The Varnish Book: Varnish Software에서 무료 제공하는 공식 가이드
• High Performance Browser Networking (O'Reilly): 웹 성능 최적화 바이블
그리고 재능넷에서 서버 최적화 전문가를 찾아서 직접 컨설팅을 받는 것도 좋은 방법이야! 이론을 실제 프로젝트에 적용하는 건 또 다른 차원의 경험이거든. 😉
이 글이 도움이 됐다면 주변 개발자 친구들에게도 공유해줘! 🙌
서버 성능 최적화는 혼자 하는 것보다 팀 전체가 이해하고 함께 적용할 때 진짜 빛을 발하거든.
댓글 작성
이 글에 대한 여러분의 생각을 들려주세요
로그인이 필요합니다
댓글을 작성하려면 먼저 로그인해주세요.
댓글 0
지식인의 숲 - 지적 재산권 보호 고지
지적 재산권 보호 고지
- 저작권 및 소유권: 본 컨텐츠는 재능넷의 독점 AI 기술로 생성되었으며, 대한민국 저작권법 및 국제 저작권 협약에 의해 보호됩니다.
- AI 생성 컨텐츠의 법적 지위: 본 AI 생성 컨텐츠는 재능넷의 지적 창작물로 인정되며, 관련 법규에 따라 저작권 보호를 받습니다.
- 사용 제한: 재능넷의 명시적 서면 동의 없이 본 컨텐츠를 복제, 수정, 배포, 또는 상업적으로 활용하는 행위는 엄격히 금지됩니다.
- 데이터 수집 금지: 본 컨텐츠에 대한 무단 스크래핑, 크롤링, 및 자동화된 데이터 수집은 법적 제재의 대상이 됩니다.
- AI 학습 제한: 재능넷의 AI 생성 컨텐츠를 타 AI 모델 학습에 무단 사용하는 행위는 금지되며, 이는 지적 재산권 침해로 간주됩니다.
아직 댓글이 없습니다.