Apache&Nginx에 Varnish Cache 설치 및 설정
기존 Apache와 Nginx 조합의 서버에 Varnish Cache를 추가로 설치하고 적용 해 보도록 하겠습니다. Nginx에 Varnish Cache를 추가로 설정하는 작업이기 때문에 기존의 서버에 적용된 사항을 체크 해 보겠습니다.
AlmaLinux release 9.4 버전에 Apache/2.4.57, nginx/1.28.0 , PHP 8.3.22를 사용하기 때문에, 설치는 varnish, collectd-varnish, varnish-modules 총 3개의 모듈 설치를 진행합니다.
OS: AlmaLinux 9.4
웹서버: Apache 2.4.57, Nginx 1.28.0
PHP 버전: 8.3.22
설치 패키지:
varnish (캐시 서버 본체)
collectd-varnish (Varnish 모니터링 플러그인)
varnish-modules (Varnish 기능 확장 모듈)
✅ Varnish Cache 설치
|
패키지 |
역할 |
설치 필요 여부 |
|---|---|---|
|
varnish |
Varnish 캐시 서버 본체 |
필수 |
|
collectd-varnish |
Varnish 모니터링 플러그인 |
필요 시 설치 |
|
varnish-modules |
Varnish 기능 확장 모듈 |
필요 시 설치 |
|
php83-php-pecl-varnish |
PHP에서 Varnish 직접 제어용 바인딩 |
PHP에서 직접 제어할 경우만 필요 |
php83-php-pecl-varnish의 경우는 Varnish를 HTTP 앞단 캐시 서버로만 사용할 목적이기 때문에 PHP용 Varnish 바인딩이 불필요해서 설치 진행을 하지 않았습니다.
dnf -y install varnish collectd-varnish varnish-modules
마지막 메타자료 만료확인(1:28:53 이전): 2025년 08월 09일 (토) 오후 09시 55분 14초.
종속성이 해결되었습니다.
==========================================================================================================
꾸러미 구조 버전 저장소 크기
==========================================================================================================
설치 중:
collectd-varnish x86_64 5.12.0-24.el9 epel 23 k
varnish x86_64 6.6.2-6.el9_6.1 appstream 1.0 M
varnish-modules x86_64 0.18.0-1.el9 appstream 81 k
종속 꾸러미 설치 중:
collectd x86_64 5.12.0-24.el9 epel 690 k
yajl x86_64 2.1.0-25.el9 appstream 37 k
연결 요약
==========================================================================================================
설치 5 꾸러미
전체 내려받기 크기: 1.8 M
설치된 크기 : 5.5 M
꾸러미 내려받기 중:
......(생략)
설치되었습니다:
collectd-5.12.0-24.el9.x86_64 collectd-varnish-5.12.0-24.el9.x86_64 varnish-6.6.2-6.el9_6.1.x86_64 varnish-modules-0.18.0-1.el9.x86_64 yajl-2.1.0-25.el9.x86_64 ✅ Apache&Nginx에 Varnish Cache 기본 설정
클라이언트 (웹 브라우저)
│
▼
+------------------+
| Nginx | ← HTTPS 443 포트에서 SSL 사용 + HTTP/3 지원 + 리버스 프록시
| (80포트에서 HTTPS로 리디렉션)
+------------------+
│ (HTTP 6081 포트로 요청 전달)
▼
+------------------+
| Varnish Cache | ← HTTP 6081 포트에서 캐시
+------------------+
│ (HTTP 8080 포트로 요청 전달)
▼
+------------------+
| Apache | ← 백엔드 웹서버 (포트 8080에서 동작)
+------------------+
│
▼
+------------------+
| PHP-FPM | ← PHP 처리
+------------------+🔲 Varnish Cache 설정 파일
1. /etc/varnish/default.vcl : 설정 파일
/etc/varnish/default.vcl 파일 설정 파일을 확인합니다.
vi /etc/varnish/default.vcl# Default backend definition. Set this to point to your content server.
backend default {
.host = "127.0.0.1";
.port = "8080";
}
sub vcl_recv {
# Happens before we check if we have this in cache already.
#
# Typically you clean up the request here, removing cookies you don't need,
# rewriting the request, etc.
}
sub vcl_backend_response {
# Happens after we have read the response headers from the backend.
#
# Here you clean the response headers, removing silly Set-Cookie headers
# and other mistakes your backend does.
}
sub vcl_deliver {
# Happens when we have all the pieces we need, and are about to send the
# response to the client.
#
# You can do accounting or modifying the final object here.
}|
서브루틴 |
실행 시점 |
주요 역할 |
|---|---|---|
|
backend default |
설정 파일 로드 시 |
원본 서버 정의. Varnish가 캐시되지 않은 콘텐츠를 요청할 서버의 주소와 포트(127.0.0.1:8080)를 지정합니다. |
|
sub vcl_recv |
클라이언트 요청 수신 시 |
요청 캐싱 정책 결정. 특정 요청(예: 관리자 페이지)을 캐시하지 않거나, 쿠키를 제거하는 등 캐싱을 위한 사전 처리를 합니다. |
|
sub vcl_backend_response |
백엔드 응답 수신 시 |
응답 캐싱 가능 여부 결정. 백엔드 서버로부터 받은 응답을 캐시할지 말지 결정합니다. 예를 들어, Set-Cookie 헤더를 제거해 캐시를 가능하게 합니다. |
|
sub vcl_deliver |
클라이언트에 응답 전송 직전 |
최종 응답 수정 및 마무리. Varnish 관련 헤더(X-Varnish, Age)를 추가하거나 수정하는 등 응답을 최종적으로 정리합니다. |
2. varnish.service
기본 원본 파일은 /usr/lib/systemd/system/varnish.service에 있으며, Varnish의 실행 환경 및 옵션을 정의하는 시스템 설정 파일입니다. 이 파일을 수정하면 Varnish가 어떤 포트에서 리스닝할지, 어떤 VCL 파일을 사용할지, 그리고 메모리 사용량은 어떻게 할지 등을 제어할 수 있습니다.
[Unit]
Description=Varnish Cache, a high-performance HTTP accelerator
After=network-online.target
[Service]
Type=forking
KillMode=process
# Maximum number of open files (for ulimit -n)
LimitNOFILE=131072
# Locked shared memory - should suffice to lock the shared memory log
# (varnishd -l argument)
# Default log size is 80MB vsl + 1M vsm + header -> 82MB
# unit is bytes
LimitMEMLOCK=85983232
# Enable this to avoid "fork failed" on reload.
TasksMax=infinity
# Maximum size of the corefile.
LimitCORE=infinity
ExecStart=/usr/sbin/varnishd -a :6081 -f /etc/varnish/default.vcl -s malloc,256m
ExecReload=/usr/sbin/varnishreload
[Install]
WantedBy=multi-user.target|
설정 항목 |
설명 |
|---|---|
|
ExecStart |
Varnish 데몬을 실행하는 핵심 명령어입니다.<br>- -a :6081: Varnish가 6081번 포트에서 요청을 받도록 지정합니다.<br>- -f /etc/varnish/default.vcl: default.vcl 파일을 캐싱 규칙으로 사용합니다.<br>- -s malloc,256m: 캐시 저장용으로 256MB의 메모리를 할당합니다. |
|
LimitNOFILE |
Varnish 프로세스가 동시에 열 수 있는 파일의 최대 개수를 설정합니다. 대규모 트래픽 환경에서 중요합니다. |
|
LimitMEMLOCK |
Varnish가 사용할 수 있는 공유 메모리의 최대 크기를 설정합니다. |
|
ExecReload |
systemctl reload varnish 실행 시, Varnish를 재시작하지 않고 설정만 다시 로드하는 명령어입니다. |
|
WantedBy |
systemctl enable 명령어를 사용해 시스템 부팅 시 자동으로 서비스가 시작되도록 설정합니다. |
3. Nginx 설정
기존 Nginx의 서버 블록 내 로케이션이 :8080이었다면 6081로 변경해 줍니다.
location / {
proxy_pass http://127.0.0.1:6081;
Varnish Cache를 활성화 합니다.
systemctl enable varnish
systemctl start varnishnginx -s reload
apachectl graceful✅ 추가 설정
varnish-modules는 기본 varnish 기능을 확장해주는 모듈 모음입니다. 설치 후에는 기본적으로 활성화만 하면 되고, 필요에 따라 VCL 파일에서 해당 모듈의 기능을 호출해 사용할 수 있습니다.
🔲 /etc/varnish/default.vcl
vcl 4.1;
# --- 백엔드 서버 정의 ---
backend default {
.host = "127.0.0.1";
.port = "8080";
}
# 클라이언트 요청이 들어올 때 실행되는 서브루틴
sub vcl_recv {
# 1. 로그인, 관리자 페이지 관련 요청은 캐시하지 않고 백엔드로 바로 전달
if (req.url ~ "(?i)/ukc_login" || req.url ~ "(?i)/wp-admin" || req.url ~ "(?i)/wp-login.php" || req.url ~ "(?i)/ghost-admin") {
return(pass);
}
# 2. POST 요청도 캐시하지 않고 백엔드로 바로 전달
if (req.method == "POST") {
return(pass);
}
}
# 백엔드 서버로부터 응답을 받은 후 실행되는 서브루틴
sub vcl_backend_response {
# Set-Cookie 헤더가 있는 응답은 캐시하지 않고 전달
if (beresp.http.Set-Cookie) {
return(deliver);
}
# HTML 콘텐츠는 3시간 캐시
if (beresp.http.Content-Type ~ "text/html") {
set beresp.ttl = 3h;
return(deliver);
}
# 정적 파일(css, js, 이미지)은 1일 캐시
if (beresp.http.Content-Type ~ "(text/css|application/javascript|application/x-javascript|image/|font/)") {
set beresp.ttl = 24h;
return(deliver);
}
}
# 클라이언트에게 응답을 전달하기 전에 실행되는 서브루틴
# 정적 콘텐츠 캐싱만 캐싱, 동적 페이지는 로그인 및 로그인 후에도 수정이 안됨
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
}🔲 서비스 파일 설정
cp /usr/lib/systemd/system/varnish.service /etc/systemd/system/varnish.service명령어를 사용하여 설정 파일을 복사하는 것을 권장하는 이유는 시스템 안정성과 유지보수 편의성 때문입니다.
/usr/lib/systemd/system/ 디렉터리는 시스템 패키지 매니저(예: dnf, apt)가 설치하고 관리하는 원본 설정 파일들이 있는 곳입니다. 만약 이 파일을 직접 수정하면, Varnish가 새로운 버전으로 업데이트될 때 변경된 설정이 덮어쓰여질 수 있습니다. 이 경우, 기존에 최적화해둔 설정이 사라지게 됩니다.
반면, /etc/systemd/system/ 디렉터리는 사용자 정의 설정 파일을 두는 곳입니다. 이곳에 파일을 복사해 수정하면, 패키지 업데이트에 영향을 받지 않고 독자적으로 설정이 유지됩니다.
cp /usr/lib/systemd/system/varnish.service /etc/systemd/system/varnish.service
vi /etc/systemd/system/varnish.service
ExecStart=/usr/sbin/varnishd -a :6081 -f /etc/varnish/default.vcl -s malloc,4Gsystemctl daemon-reload
systemctl restart varnishApache&Nginx에 Varnish Cache 설정이 완료 되었습니다.
✅ varnishstat 명령어
# 캐시의 상태를 보여줌
varnishstat
# 캐시 상태를 1번 출력
varnishstat -1
varnishstat -1 | grep SMAvarnishstat -1 | grep MAIN.cacheMAIN.cache_hit 173 0.06 Cache hits
MAIN.cache_hit_grace 0 0.00 Cache grace hits
MAIN.cache_hitpass 0 0.00 Cache hits for pass.
MAIN.cache_hitmiss 0 0.00 Cache hits for miss.
MAIN.cache_miss 210 0.08 Cache misses|
항목 |
의미 |
설명 |
|---|---|---|
|
MAIN.cache_hit |
⚡ 캐시 히트 |
요청이 캐시에서 바로 응답 된 횟수 |
|
MAIN.cache_hit_grace |
⏳ grace 히트 |
TTL은 지났지만 grace 기간 내 응답된 횟수 |
|
MAIN.cache_hitmiss |
🤷 hit-for-miss |
miss로 처리되었지만 캐시된 횟수 (드물게 사용됨) |
|
MAIN.cache_hitpass |
🚫 pass 히트 |
pass 처리된 요청 중 캐시된 횟수 |
|
MAIN.cache_miss |
❌ 캐시 미스 |
캐시에 없어서 백엔드로 간 횟수 |
varnishstat -1 | grep s0MEMPOOL.sess0.live 0 . In use
MEMPOOL.sess0.pool 10 . In Pool
MEMPOOL.sess0.sz_wanted 768 . Size requested
MEMPOOL.sess0.sz_actual 736 . Size allocated
MEMPOOL.sess0.allocs 352 0.12 Allocations
MEMPOOL.sess0.frees 352 0.12 Frees
MEMPOOL.sess0.recycle 352 0.12 Recycled from pool
MEMPOOL.sess0.timeout 62 0.02 Timed out from pool
MEMPOOL.sess0.toosmall 0 0.00 Too small to recycle
MEMPOOL.sess0.surplus 0 0.00 Too many for pool
MEMPOOL.sess0.randry 0 0.00 Pool ran dry
SMA.s0.c_req 870 0.30 Allocator requests
SMA.s0.c_fail 0 0.00 Allocator failures
SMA.s0.c_bytes 10277220 3548.76 Bytes allocated
SMA.s0.c_freed 1130496 390.36 Bytes freed
SMA.s0.g_alloc 801 . Allocations outstanding
SMA.s0.g_bytes 9146724 . Bytes outstanding
SMA.s0.g_space 4285820572 . Bytes available|
항목 |
값 |
설명 |
|---|---|---|
|
live |
0 |
현재 사용 중인 세션 없음 (idle 상태) |
|
pool |
10 |
풀에 대기 중인 세션 객체 수 |
|
allocs / frees |
352 |
세션 객체 할당/해제 횟수 |
|
recycle |
352 |
재사용된 세션 객체 수 (풀 잘 작동 중) ⚡ |
|
timeout |
62 |
풀에서 꺼내려다 시간 초과된 횟수 |
|
toosmall / surplus / randry |
0 |
문제 없음 (풀 부족/과잉 없음) ⚡ |
👉 요약: 세션 풀은 안정적으로 작동 중이며, 재사용률도 높고 문제 없음.
|
항목 |
값 |
설명 |
|---|---|---|
|
c_req |
870 |
메모리 요청 횟수 |
|
c_fail |
0 |
메모리 할당 실패 없음 💾 |
|
c_bytes |
10.27 MB |
총 할당된 메모리 |
|
c_freed |
1.13 MB |
총 해제된 메모리 |
|
g_alloc |
801 |
현재 살아있는 할당 수 |
|
g_bytes |
9.15 MB |
현재 사용 중인 메모리 |
|
g_space |
4.28 GB |
남은 공간 (매우 넉넉함) 💾 |
👉 요약: malloc 스토리지도 안정적이며, 메모리 여유 충분. 할당 실패 없음.