CHIA SẺ:
Post Series: Varnish
  1. 1. Hướng dẫn cài đặt Varnish cho Nginx/Apache trên CentOS/Ubuntu
  2. 2. Varnish Agent – Công cụ quản lý và Theo dõi Varnish
  3. 3. Varnish Dashboard – Theo dõi Varnish trực quan, realtime
  4. 4. Cấu hình Varnish hoạt động với CloudFlare và Nginx
  5. 5. Cấu hình Varnish hoạt động trên 2 port khác nhau
  6. 6. Sử dụng HTTPS với Varnish

Trong bài viết này mình sẽ hướng dẫn bạn cách cài đặt và sử dụng Varnish làm front-end cho Nginx hoặc Apache để cache các request HTTP nhanh hơn mà không cần phải nhờ đến webserver xử lý.

Varnish Cache

Varnish là một hệ thống cache được dùng để tăng tốc server, đặc biệt là với những hệ thống lớn, có trafic nhiều. Varnish hoạt động bằng cách cache nội dung page lên bộ nhớ RAM và ngay lập tức trả lại cho người dùng khi có yêu cầu mà không phải thông qua PHP hay MySQL xử lý.

Do sử dụng Memory để cache nên tốc độ truy xuất sẽ nhanh hơn rất nhiều so với Disk truyền thống, kể cả SSD. Bạn thử tưởng tượng với những website có lượng lớn dữ liệu, phương pháp cache thông thường sẽ tạo ra hàng vạn file .html trên ổ cứng, lúc đó PHP hoặc Nginx xử lý sẽ cực kỳ vất vả, tốn tài nguyên.

Varnish hoạt động rất tốt với những website có dữ liệu lớn, một số website lớn trên thế giới đang áp dụng Varnish như Wikipedia, The New York Times, The Guardian, Facebook, Twitter, Vimeo, Canh Me

Một số nhà cung cấp shared hosting cũng hỗ trợ sẵn Varnish như StableHost, SiteGround (chỉ những gói cao cấp). Nếu không muốn cài đặt vất vả, bạn có thể sử dụng luôn hosting ở đây.

Quá trình cài đặt và cấu hình Varnish Cache khá phức tạp, tuy nhiên điều này rất đáng để thử vì sau khi hoàn thành, website của bạn chắc chắn load vù vù cho coi.

I. Cài đặt Varnish

Bạn cần cài đặt trước LEMP hoặc LAMP server trước khi tiến hành cài đặt Varnish. Nếu chưa cài đặt, hãy tham khảo HocVPS Script, LEMP hoặc LAMP.

Với Ubuntu

aptitude update && aptitude install varnish

Với CentOS 6

yum install epel-release
rpm --nosignature -i https://repo.varnish-cache.org/redhat/varnish-4.0.el6.rpm
yum install varnish

Với CentOS 7

yum install epel-release
rpm --nosignature -i https://repo.varnish-cache.org/redhat/varnish-4.0.el7.rpm
yum install varnish

Sau khi cài đặt thành công, tùy thuộc vào OS mà bạn đang sử dụng mà Varnish có phiên bản khác nhau:

  1. Ubuntu: 3.0.2-1
  2. CentOS: v4.0.3

Việc xác định phiên bản Varnish rất quan trọng, vì Varnish 3.0 có cách cấu hình, tham số khác hoàn toàn Varnish 4.0. Bạn có thể kiểm tra phiên bản sau khi cài đặt xong bằng lệnh varnishd -V

varnishd (varnish-4.0.3 revision b8c4a34)
Copyright (c) 2006 Verdens Gang AS
Copyright (c) 2006-2014 Varnish Software AS

Xem thêm hướng dẫn cài đặt trên CentOS/Redhat tại đây.

Một số hệ thống sử dụng OS x32 khi cài thì bị lỗi [Errno 14] PYCURL ERROR 22 - "The requested URL returned error: 404 Not Found", các bạn chuyển sang x64 nhé.

Kích hoạt Varnish tự động chạy

Với Ubuntu, CentOS 6.x

chkconfig --add varnish
chkconfig varnish on

Với CentOS 7.x

systemctl status varnish
system enable varnish

II. Cấu hình Varnish

Có 2 file cấu hình bạn cần biết trước khi làm việc với Varnish:

1. File cấu hình tham số để Varnish hoạt động được

  • /etc/sysconfig/varnish trên CentOS 6.x hoặc
  • /etc/default/varnish trên Ubuntu hoặc
  • /etc/varnish/varnish.params trên CentOS 7.

2. File cấu hình VCL (Varnish Configuration Language) chứa các rule caching, /etc/varnish/default.vcl

Quy trình tiến hành cấu hình Varnish như sau:

  1. Thay đổi port để Varnish listen thành 80
  2. Thay đổi port để Web server listen thành 8080, hoặc port bất kỳ bạn muốn
  3. Varnish tự động kết nối đến web server khi có request

1. Cấu hình Varnish

Phiên bản Hệ điều hành Đường dẫn file Cấu hình tham khảo
Varnish 3 Ubuntu /etc/default/varnish
VARNISH_VCL_CONF=/etc/varnish/default.vcl
VARNISH_LISTEN_ADDRESS=
VARNISH_LISTEN_PORT=80
VARNISH_MIN_THREADS=100
VARNISH_MAX_THREADS=5000
VARNISH_THREAD_TIMEOUT=120
VARNISH_STORAGE_SIZE=256M
VARNISH_STORAGE="malloc,${VARNISH_STORAGE_SIZE}"
VARNISH_SECRET_FILE=/etc/varnish/secret
VARNISH_TTL=120
Varnish 4 CentOS 6.x /etc/sysconfig/varnish
Varnish 4 CentOS 7 /etc/varnish/varnish.params
VARNISH_STORAGE="malloc,512M"

Bạn có thể thay đổi một số tham số mình thấy tối ưu nhất cho Varnish như sau:

  • thread_pool_min (VARNISH_MIN_THREADS) mặc định là 100, thay bằng 800/(số CPU Core). Ví dụ mình có 4 Core -> VARNISH_MIN_THREADS=200
  • thread_pool_max (VARNISH_MAX_THREADS) mặc định 5000, tuyệt đối không cấu hình quá 5000

VARNISH_STORAGE có 2 loại là mallocfilemalloc lưu cache trên Memory, có tốc độ xử lý cao hơn nhiều so với file lưu trên ổ cứng.

Xem thêm Varnish Tuning.

Cấu hình file VCL cho Varnish 4 để hoạt động được với WordPress

Do mình sử dụng WordPress và CentOS nhiều nên có chuẩn bị được file cấu hình VLC tối ưu này, các bạn có thể tham khảo sử dụng.

nano /etc/varnish/default.vcl

Thay thế toàn bộ bằng nội dung sau:

vcl 4.0;

backend default {
    .host = "127.0.0.1";
    .port = "8080";
    .first_byte_timeout = 300s;
}

acl purge {
    "127.0.0.1";
}

sub vcl_recv {
        if (req.method == "PURGE") {
            if (!client.ip ~ purge) {
              return(synth(405,"Not allowed."));
            }

                if (req.http.X-Purge-Method == "regex") {
                        ban("req.url ~ " + req.url + " && req.http.host ~ " + req.http.host);
                        return (synth(200, "Banned."));
                } else {
                        return (purge);
                }
        }

        ### Do not Authorized requests.
        if (req.http.Authorization) {
                return(pass); // DO NOT CACHE
        }

        ### Pass any requests with the "If-None-Match" header directly.
        if (req.http.If-None-Match) {
                return(pass); // DO NOT CACHE
        }

        ### Do not cache AJAX requests.
        if (req.http.X-Requested-With == "XMLHttpRequest") {
                return(pass); // DO NOT CACHE
        }

        ### Only cache GET or HEAD requests. This makes sure the POST (and OPTIONS) requests are always passed.
        if (req.method != "GET" && req.method != "HEAD") {
                return (pass); // DO NOT CACHE
        }

        ### Static files: Do not cache PDF, XML, ... files (=static & huge and no use caching them - in all Vary: variations!)
        if (req.url ~ "\.(doc|mp3|pdf|tif|tiff|xml)(\?.*|)$") {
                return(pass); // DO NOT CACHE
        }

        # Unset the header for static files
        if (req.url ~ "\.(gif|jpg|jpeg|swf|ttf|css|js|flv|mp3|mp4|pdf|ico|png)(\?.*|)$") {
                unset req.http.cookie;
                set req.url = regsub(req.url, "\?.*$", "");
        }

        if (req.url ~ "\?(utm_(campaign|medium|source|term)|adParams|client|cx|eid|fbid|feed|ref(id|src)?|v(er|iew))=") {
                set req.url = regsub(req.url, "\?.*$", "");
        }

        if (req.url ~ "wp-(login|admin)" || req.url ~ "preview=true" || req.url ~ "xmlrpc.php") {
                return (pass);
        }

        if (req.http.cookie) {
                # Google Analytics
                set req.http.Cookie = regsuball( req.http.Cookie, "(^|;\s*)(__utm[a-z]+)=([^;]*)", "");
                set req.http.Cookie = regsuball( req.http.Cookie, "(^|;\s*)(_ga)=([^;]*)", "");

                # Quant Capital
                set req.http.Cookie = regsuball( req.http.Cookie, "(^|;\s*)(__qc[a-z]+)=([^;]*)", "");

                # __gad __gads
                set req.http.Cookie = regsuball( req.http.Cookie, "(^|;\s*)(__gad[a-z]+)=([^;]*)", "");

                # Google Cookie consent (client javascript cookie)
                set req.http.Cookie = regsuball( req.http.Cookie, "(^|;\s*)(displayCookieConsent)=([^;]*)", "");

                # Other known Cookies: remove them (if found).
                set req.http.Cookie = regsuball( req.http.Cookie, "(^|;\s*)(__CT_Data)=([^;]*)", "");
                set req.http.Cookie = regsuball( req.http.Cookie, "(^|;\s*)(WRIgnore|WRUID)=([^;]*)", "");


                # PostAction: Remove (once and if found) a ";" prefix followed by 0..n whitespaces.
                # INFO \s* = 0..n whitespace characters
                set req.http.Cookie = regsub( req.http.Cookie, "^;\s*", "" );

                # PostAction: Unset the header if it is empty or 0..n whitespaces.
                if ( req.http.cookie ~ "^\s*$" ) {
                        unset req.http.Cookie;
                }
        }
}

sub vcl_backend_response {
        if ( (!(bereq.url ~ "(wp-(login|admin)|login)")) || (bereq.method == "GET") ) {
                //unset beresp.http.set-cookie;
                set beresp.ttl = 1h;
        }
        # Remove some headers we never want to see
        unset beresp.http.Server;
        unset beresp.http.X-Powered-By;

        if (bereq.url ~ "\.(gif|jpg|jpeg|swf|ttf|css|js|flv|mp3|mp4|pdf|ico|png)(\?.*|)$") {
                unset beresp.http.cookie;
                set beresp.ttl = 365d;
        }

        set beresp.ttl = 10s;
        set beresp.grace = 1h;
}

sub vcl_deliver {
    if (obj.hits > 0) {
      set resp.http.X-Cache = "HIT";
    } else {
      set resp.http.X-Cache = "MISS";
    }
    set resp.http.Access-Control-Allow-Origin = "*";
    set resp.http.Server = "HocVPS Script";
}

Bạn có thể test cấu hình VCL với lệnh bên dưới, nếu không xuất hiện lỗi gì là ok. Thoát varnishd bằng cách nhấn Ctrl+C

varnishd -F -f /etc/varnish/default.vcl

Khi update file cấu hình default.vcl, các bạn có thể reload Varnish vẫn giữ nguyên cache sử dụng init.d scripts:

/etc/init.d/varnish reload

hoặc thông qua Varnish Reload VCL script

varnish_reload_vcl

2. Cấu hình Web server

– Tiếp theo hãy chỉnh sửa file cấu hình của Web server để thay đổi port listen từ 80 thành 8080

Web Server Hệ điều hành File cấu hình Nội dung thay đổi
Apache Ubuntu /etc/apache2/ports.conf NameVirtualHost 127.0.0.1:8080
Listen 8080
/etc/apache2/sites-available/default
CentOS /etc/httpd/conf/httpd.conf Listen 8080
Nginx Ubuntu /etc/nginx/sites-enabled/default listen 127.0.0.1:8080 trong block server.
CentOS /etc/nginx/nginx.conf

Nếu dùng HocVPS Script thì bạn cấu hình lại toàn bộ tên miền ở folder /etc/nginx/conf.d/ chuyển listen 80; thành listen 127.0.0.1:8080;

– Điều chỉnh để hiển thị IP thật của visitor trong log file, thay vì 127.0.0.1.

Bạn hãy mở file cấu hình nginx:

nano /etc/nginx/nginx.conf

Thay đoạn log_format

        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                     '$status $body_bytes_sent "$http_referer" '
                     '"$http_user_agent" "$http_x_forwarded_for"';

bằng đoạn sau:

        set_real_ip_from        127.0.0.1;
        real_ip_header          X-Forwarded-For;
        log_format      main '$remote_addr - $remote_user [$time_local]  $status '
                '"$request" $body_bytes_sent "$http_referer" '
                '"$http_user_agent" "$http_x_forwarded_for"';

Cuối cùng hãy restart Varnish và Web server.

Giờ bạn có thể truy cập vào IP để check xem hệ thống đã hoạt động chưa rồi đó.

Nếu sử dụng WordPress bạn hãy cài đặt thêm plugin Varnish HTTP Purge để tự động xóa cache khi publish hoặc update bài viết.

Để kiểm tra các service nào đang listen port, ví dụ 80, bạn có thể sử dụng lệnh: netstat -lntp | grep 80.

III. Testing Varnish

Để biết được Varnish có đang hoạt động hay không bạn sử dụng lệnh bên dưới:

curl -I domain.com

Lần đầu tiên chạy, để ý dòng X-Varnish bạn sẽ thấy một số, ví dụ:

X-Varnish: 1482416538

hoặc X-Cache: MISS

Sử dụng lệnh bên trên lần thứ 2, nếu thấy xuất hiện 2 số tức là Varnish đã hoạt động rồi đó, ví dụ:

X-Varnish: 1482416539 1482416538

hoặc X-Cache: HIT

Ngoài ra, bạn cũng có thể sử dụng 2 công cụ:

  1. varnishlog: xem Varnish logsreal time
  2. varnishstat: hiển thị tình trạng cache Varnish

Chúc bạn  thành công!

164 Comments

  1. hanh 1

    Bạn Luân ơi !

    cho mình hỏi, mình có 5 trang web trên 1 VPS, giờ muốn 4 trang sử dụng Varnish, còn 1 trang thì không sử dụng thì có làm được ? nếu được thì cấu hình thế nào ?

  2. long 2

    cho mình hỏi cái vanish này bao lâu thì nó tự xóa cache, hay là mình phải xóa = tay vậy

    1. Dinh Le Giang 47

      Nếu bạn cài trên Centos và Varnish 4 thì làm theo cách này
      Bạn chạy lệnh sudo nano /etc/varnish/default.vcl
      Ở dòng sub vcl_backend_response {
      Bạn thêm 2 code sau vào (cái này là 1 tiếng đó)
      set beresp.ttl = 600s;
      set beresp.grace = 600s;
      Sau đó lưu lại bằng cách nhấn phím Ctrl + O và thoát bằng Ctrl + X rồi chạy lệnh service varnish restart để khởi động lại dịch vụ

    2. Luân Trần Admin

      Khi nào nội dung website thay đổi thì nó tự động cập nhật cache. Với những file tĩnh như .css, .js thì thời gian có thể lâu hơn.
      Ngoài cách của Dinh Le Giang, có thể xóa chủ động bằng cách vào Varnish Dashboard (Varnish Agent cũng được), Manage Server rồi Clear Panic

  3. haint 4

    Hi Luân . mình đang bị lỗi này. Port Nginx cấu hình chưa đúng

    [root@vps conf.d]# vi /etc/nginx/nginx.conf
    [root@vps conf.d]# service nginx restart
    Stopping nginx: [FAILED]
    Starting nginx: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
    nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
    nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
    nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
    nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
    nginx: [emerg] still could not bind()

    1. Luân Trần Admin

      Do cấu hình ở đâu vẫn dùng port 80 rồi, bạn check lại toàn bộ các file .conf nha

  4. Trong Tri 11

    Luân ơi, cài xong mình check thấy bị MISS rồi đã thử nhiều lần, mình sử dụng Directadmin.

    curl -I thietkewp.com
    HTTP/1.1 200 OK
    Date: Tue, 11 Oct 2016 04:11:51 GMT
    Content-Type: text/html; charset=UTF-8
    Expires: Thu, 19 Nov 1981 08:52:00 GMT
    Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
    Pragma: no-cache
    Link: ; rel=”https://api.w.org/”
    Set-Cookie: PHPSESSID=er3d7cg0ecsikt4v9qufdhuh90; path=/
    Vary: Accept-Encoding,User-Agent
    X-Varnish: 32831
    Age: 0
    Via: 1.1 varnish-v4
    X-Cache: MISS
    Access-Control-Allow-Origin: *
    Server: HocVPS Script
    Connection: keep-alive

  5. Nguyên Hào 18

    system enable varnish

    lệnh này trên CentOS7 , ko chạy được Luân đại ka ơi

  6. Nguyên Hào 18

    Luân cho mình hỏi thêm , là khi cài đặt Vanish xong cho web của mình , nó lại trỏ về web mặc định khi cài Hocvps , khắc phục lỗi này thế nào Luân nhỉ . Thanks

  7. Tran Hung 17

    cho hỏi mình thâý bạn hướng dẫn chỗ này
    thread_pools mặc định 2, thay bằng số CPU Core
    nó nằm ở đâu vậy? trong file varnish.params mình chỉ để các thông tin này
    VARNISH_VCL_CONF=/etc/varnish/default.vcl
    VARNISH_LISTEN_ADDRESS=
    VARNISH_LISTEN_PORT=80
    VARNISH_MIN_THREADS=100
    VARNISH_MAX_THREADS=5000
    VARNISH_THREAD_TIMEOUT=120
    VARNISH_STORAGE=”malloc,1024M”
    VARNISH_SECRET_FILE=/etc/varnish/secret
    VARNISH_TTL=120
    VARNISH_USER=varnish
    VARNISH_GROUP=varnish

    1. Luân Trần Admin

      Cái đó của phiên bản Varnish khác, nếu không có thì bạn bỏ đi nhé.

          1. Việt Phương Moderator

            Chưa bàn đến memcached, phần bạn test Varnish vẫn chưa OK mà

  8. Le Dinh Nhon 1

    Cho mình hỏi, mình đã đổi port 6081 -> 80 trong /etc/default/varnish rồi mà tại sao khi gõ lệnh service varnish restart – > netstat -ntlup thì varnish vẫn còn là 6081.

    Giúp mình với nhé !

Comment của bạn

Your email address will not be published. Required fields are marked *