เร่งเว็บด้วย Varnish Cache บน VPS Nginx
Varnish Cache เป็น HTTP accelerator ที่เก็บ page ทั้งหน้าไว้ใน RAM เมื่อ visitor เข้าหน้าซ้ำ Varnish ตอบจาก memory โดยตรงโดยไม่แตะ PHP หรือ database เลย ทำให้ response time ลดจาก 200-500ms เหลือ 1-5ms ในทางปฏิบัติ Varnish สามารถรับ traffic ได้มากกว่า Nginx ล้วนๆ หลายเท่า
Architecture: Nginx (443) → Varnish (80) → Nginx (8080)
# Nginx รับ HTTPS ที่ port 443
# Varnish รับที่ port 80 (หรือผ่าน Nginx proxy)
# Backend Nginx/Apache ที่ port 8080
# ในบทความนี้ใช้ architecture:
# Client → Nginx:443 (SSL termination) → Varnish:6081 → Nginx:8080 (backend)
ติดตั้ง Varnish
sudo apt update
sudo apt install varnish -y
# ตรวจ
varnishd -V
แก้ Backend Port ใน Nginx
# แก้ Nginx ให้ listen port 8080 แทน 80
sudo nano /etc/nginx/sites-available/yourdomain.com
server {
listen 8080; # เปลี่ยนจาก 80 เป็น 8080
server_name yourdomain.com;
# ... config เดิม
}
sudo nginx -t && sudo systemctl reload nginx
ตั้ง Varnish Config (VCL)
sudo nano /etc/varnish/default.vcl
vcl 4.0;
backend default {
.host = "127.0.0.1";
.port = "8080";
}
sub vcl_recv {
# ไม่ cache request ที่มี cookie (logged-in users)
if (req.http.Cookie) {
if (req.http.Cookie !~ "wordpress_logged_in") {
unset req.http.Cookie;
}
}
# ไม่ cache admin pages
if (req.url ~ "^/wp-admin|^/wp-login.php") {
return(pass);
}
# ไม่ cache POST request
if (req.method == "POST") {
return(pass);
}
}
sub vcl_backend_response {
# Cache HTML 1 ชั่วโมง
if (beresp.http.Content-Type ~ "text/html") {
set beresp.ttl = 1h;
set beresp.grace = 24h;
}
# ไม่ cache ถ้า backend บอก no-store
if (beresp.http.Cache-Control ~ "no-store|private") {
set beresp.uncacheable = true;
}
}
sub vcl_deliver {
# ใส่ header บอกว่า cache hit หรือ miss (debug)
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
}
ตั้ง Varnish ให้ Listen Port 6081
sudo nano /etc/varnish/varnish.params
VARNISH_VCL_CONF=/etc/varnish/default.vcl
VARNISH_LISTEN_PORT=6081
VARNISH_STORAGE="malloc,256m" # ใช้ RAM 256MB
VARNISH_TTL=120
sudo systemctl restart varnish
ตั้ง Nginx Forward ไปที่ Varnish
sudo nano /etc/nginx/sites-available/yourdomain.com
server {
listen 443 ssl;
server_name yourdomain.com;
ssl_certificate ...;
ssl_certificate_key ...;
location / {
proxy_pass http://127.0.0.1:6081;
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 https;
}
}
sudo nginx -t && sudo systemctl reload nginx
varnishstat -1 เน้นที่ cache_hit และ cache_miss hit rate ควรอยู่ที่ 80%+ สำหรับเว็บ content ปกติ
ตรวจสอบว่า Varnish ทำงานถูกต้อง
# ตรวจ service
sudo systemctl status varnish
# ดู hit/miss
curl -I https://yourdomain.com | grep X-Cache
# ครั้งแรก: X-Cache: MISS
# ครั้งที่สอง: X-Cache: HIT
# ดู statistics
varnishstat -1 | grep cache_hit
# ดู realtime log
varnishlog -i ReqURL,ReqHeader,RespHeader
curl -X PURGE http://127.0.0.1:6081/path/to/page ใช้ใน WordPress plugins หรือ deploy script เพื่อ invalidate cache เมื่ออัพเดท content
แก้ปัญหาที่พบบ่อย
Cache hit rate ต่ำมาก (ต่ำกว่า 50%)
ส่วนใหญ่เกิดจาก Cookie ทำให้ Varnish bypass cache ดู cookie ที่ส่งมา:
varnishlog -g request -q "RespHeader:X-Cache eq MISS" -i ReqHeader
WordPress admin page ช้า (ผ่าน Varnish)
VCL ต้อง pass admin pages ให้ผ่านโดยไม่ cache ตรวจ VCL rule:
if (req.url ~ "^/wp-admin|^/wp-login.php|^/wp-cron.php") {
return(pass);
}
HTTPS ไม่ทำงานผ่าน Varnish
Varnish ไม่รองรับ SSL โดยตรง ต้อง terminate SSL ที่ Nginx ก่อน แล้ว proxy มาที่ Varnish เป็น HTTP
Error "503 Backend fetch failed"
Backend (Nginx port 8080) ไม่ตอบสนอง ตรวจ port:
ss -tlnp | grep 8080
sudo systemctl status nginx
คำถามที่พบบ่อย
Varnish กับ Nginx FastCGI cache ต่างกันอย่างไร?
Nginx FastCGI cache เก็บ cache ไว้ใน disk Varnish เก็บไว้ใน RAM ทำให้ Varnish เร็วกว่า 10-100 เท่า แต่ restart Varnish ทำให้ cache หาย ต้อง warm-up ใหม่
Varnish ต้องการ RAM เท่าไหร่?
ขึ้นอยู่กับขนาดเว็บ ทั่วไปตั้ง 25-50% ของ VPS RAM สำหรับ cache เว็บขนาดกลาง 256-512 MB เพียงพอ ถ้า RAM น้อยกว่า content cache Varnish จะ evict page เก่าออกอัตโนมัติ
ใช้ Varnish กับ Cloudflare ได้ไหม?
ได้ Cloudflare cache ที่ edge CDN Varnish cache ที่ server ทำงานร่วมกันได้ดี Cloudflare จะ miss ไปที่ origin แล้ว Varnish ตอบจาก RAM แทน PHP ลด origin load อีกชั้น